From 1c6923268de1e1f49b6224025640776438955c48 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Sat, 1 Dec 2018 10:57:05 -0600 Subject: [PATCH 01/25] #12: Persist the lock to database. --- .../database/storage/db/MatchEntry.java | 5 ++++ .../storage/db/server/DataBaseManager.java | 14 ++++++++-- .../storage/db/server/MatchService.java | 26 +++++++++---------- .../storage/db/server/MatchServiceTest.java | 4 +-- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java index 5582683..b6ac298 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java @@ -2,6 +2,7 @@ import java.io.Serializable; import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import javax.persistence.Basic; @@ -65,21 +66,25 @@ public class MatchEntry implements Serializable public MatchEntry() { + matchHasTeamList= new ArrayList<>(); } public MatchEntry(MatchEntryPK matchEntryPK) { + this(); this.matchEntryPK = matchEntryPK; } public MatchEntry(MatchEntryPK matchEntryPK, LocalDate matchDate) { + this(); this.matchEntryPK = matchEntryPK; this.matchDate = matchDate; } public MatchEntry(int formatId, int formatGameId) { + this(); this.matchEntryPK = new MatchEntryPK(formatId, formatGameId); } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index 84cc773..1f677b7 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -551,10 +551,20 @@ public static void loadDemoData() throws Exception MatchService.getInstance().setResult(match.getMatchHasTeamList().get(1), MatchService.getInstance().getResultType(win ? "result.loss" : "result.win").get()); - + //Lock the results so records are updated. match.getMatchHasTeamList().forEach(mht - -> MatchService.getInstance().lockMatchResult(mht.getMatchResult())); + -> + { + try + { + MatchService.getInstance().lockMatchResult(mht.getMatchResult()); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + }); } } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index 45d326d..e24fa7a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -135,15 +135,9 @@ public List findMatchesWithFormat(String format) * @param key Key for the match. * @return Match or null if not found. */ - public List findMatch(MatchEntryPK key) + public MatchEntry findMatch(MatchEntryPK key) { - List results = new ArrayList<>(); - MatchEntry match = mc.findMatchEntry(key); - if (match != null) - { - results.add(match); - } - return results; + return mc.findMatchEntry(key); } /** @@ -166,10 +160,13 @@ public boolean addTeam(MatchEntry match, Team team) throws Exception MatchHasTeam mht = new MatchHasTeam(); mht.setTeam(team); mht.setMatchEntry(match); - mht.setMatchHasTeamPK(new MatchHasTeamPK(team.getId(), - match.getMatchEntryPK().getId(), - match.getMatchEntryPK().getFormatId(), - match.getFormat().getGame().getId())); + if (match.getMatchEntryPK() != null) + { + mht.setMatchHasTeamPK(new MatchHasTeamPK(team.getId(), + match.getMatchEntryPK().getId(), + match.getMatchEntryPK().getFormatId(), + match.getFormat().getGame().getId())); + } if (match.getMatchEntryPK() != null) { @@ -272,7 +269,7 @@ public void setResult(MatchHasTeam mht, MatchResultType mrt) * * @param mr Match Result to lock. */ - public void lockMatchResult(MatchResult mr) + public void lockMatchResult(MatchResult mr) throws Exception { mr.setLocked(true); @@ -290,7 +287,7 @@ public void lockMatchResult(MatchResult mr) case "result.draw": record.setDraws(record.getDraws() + 1); break; - //Various reasons leading to a win. + //Various reasons leading to a win. case "result.win": //Fall thru case "result.forfeit": @@ -309,5 +306,6 @@ public void lockMatchResult(MatchResult mr) } }); }); + mrc.edit(mr); } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index 6a5cd4c..ea3b8fa 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -52,7 +52,7 @@ public void testMatchService() throws TournamentException, Exception MatchService.getInstance().saveMatch(me); MatchEntry match - = MatchService.getInstance().findMatch(me.getMatchEntryPK()).get(0); + = MatchService.getInstance().findMatch(me.getMatchEntryPK()); assertNotNull(me.getFormat()); assertNotNull(match.getFormat()); @@ -76,7 +76,7 @@ public void testMatchService() throws TournamentException, Exception } }); - match = MatchService.getInstance().findMatch(me.getMatchEntryPK()).get(0); + match = MatchService.getInstance().findMatch(me.getMatchEntryPK()); assertEquals(match.getMatchHasTeamList().size(), 2); assertNotNull(match.getFormat()); From 17b37c794a55f3448f7571e3be47d2c81deab785 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Sat, 1 Dec 2018 12:24:47 -0600 Subject: [PATCH 02/25] #12: Allow to lock from UI. Disable/enable buttons based on lock state. --- .../ui/views/matchlist/MatchEditorDialog.java | 6 --- .../manager/ui/views/matchlist/MatchList.java | 29 +++++++++--- .../ui/views/matchlist/ResultForm.java | 46 ++++++++++++++++++- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java index 5405bcb..c24be92 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java @@ -17,7 +17,6 @@ import static com.github.javydreamercsw.tournament.manager.ui.views.TMView.CURRENT_GAME; -import java.time.LocalDate; import java.util.List; import java.util.Objects; import java.util.function.BiConsumer; @@ -170,11 +169,6 @@ public void valueChanged(ValueChangeEvent e) } }); getFormLayout().add(datePicker); - - if (datePicker.getValue() == null) - { - datePicker.setValue(LocalDate.now()); - } } @Override diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java index fde510f..c8f7281 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java @@ -22,6 +22,7 @@ import org.openide.util.Exceptions; import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.MatchHasTeam; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.server.MatchService; import com.github.javydreamercsw.tournament.manager.ui.MainLayout; @@ -158,24 +159,40 @@ private Button createEditButton(MatchEntry me) edit.setIcon(new Icon("lumo", "edit")); edit.addClassName("match__edit"); edit.getElement().setAttribute("theme", "tertiary"); + edit.setEnabled(isMatchLocked(me)); return edit; } private Button resultButton(MatchEntry me) { - Button edit = new Button("Results", event -> + Button result = new Button("Results", event -> { // List all the teams so results can be seen/set. Dialog dialog = new Dialog(); - dialog.add(new ResultForm(me)); + dialog.add(new ResultForm(this, dialog, me)); dialog.setCloseOnOutsideClick(true); dialog.setHeight("25em"); dialog.setWidth("75em"); dialog.open(); }); - edit.setIcon(new Icon("lumo", "edit")); - edit.addClassName("match__result"); - edit.getElement().setAttribute("theme", "tertiary"); - return edit; + result.setIcon(new Icon("lumo", "edit")); + result.addClassName("match__result"); + result.getElement().setAttribute("theme", "tertiary"); + result.setEnabled(isMatchLocked(me)); + return result; + } + + private boolean isMatchLocked(MatchEntry me) + { + boolean enable = false; + for (MatchHasTeam mht : me.getMatchHasTeamList()) + { + if (mht.getMatchResult() == null || !mht.getMatchResult().getLocked()) + { + enable = true; + break; + } + } + return enable || me.getMatchHasTeamList().isEmpty(); } @Override diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java index a5d5b93..5b3dedb 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java @@ -8,7 +8,9 @@ import com.github.javydreamercsw.database.storage.db.server.MatchService; import com.vaadin.flow.component.HasValue.ValueChangeEvent; import com.vaadin.flow.component.HasValue.ValueChangeListener; +import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.dialog.Dialog; import com.vaadin.flow.component.formlayout.FormLayout; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.html.Label; @@ -19,9 +21,12 @@ public class ResultForm extends FormLayout { private static final long serialVersionUID = -777301071814867123L; private Grid resultGrid = new Grid<>(); + private Button lock = new Button("Lock Results"); + private final MatchEntry entry; - public ResultForm(MatchEntry me) + public ResultForm(MatchList ml,Dialog dialog, MatchEntry me) { + this.entry = me; resultGrid.addColumn(new ComponentRenderer<>((mht) -> new Label(mht.getTeam().getName()))).setHeader("Team") .setWidth("8em").setResizable(true); @@ -36,6 +41,7 @@ public ResultForm(MatchEntry me) if (mht.getMatchResult() != null) { cb.setValue(mht.getMatchResult().getMatchResultType()); + cb.setEnabled(!mht.getMatchResult().getLocked()); } cb.addValueChangeListener(new ValueChangeListener() { @@ -47,6 +53,7 @@ public void valueChanged(ValueChangeEvent e) try { MatchService.getInstance().setResult(mht, cb.getValue()); + validate(); } catch (Exception ex) { @@ -57,6 +64,43 @@ public void valueChanged(ValueChangeEvent e) return cb; })).setHeader("Result").setWidth("8em").setResizable(true); resultGrid.setItems(me.getMatchHasTeamList()); + lock.addClickListener(event -> + { + MatchService.getInstance().findMatch(entry.getMatchEntryPK()) + .getMatchHasTeamList().forEach((mht) -> + { + try + { + MatchService.getInstance().lockMatchResult(mht.getMatchResult()); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + }); + dialog.close(); + ml.updateView(); + }); + add(lock); add(resultGrid); + validate(); + } + + private void validate() + { + boolean valid = true; + if (entry != null) + { + for (MatchHasTeam mht : MatchService.getInstance() + .findMatch(entry.getMatchEntryPK()).getMatchHasTeamList()) + { + if (mht.getMatchResult() == null || mht.getMatchResult().getLocked()) + { + valid = false; + break; + } + } + } + lock.setEnabled(valid); } } From 8a1d90eb3a4dee2d0c13516bfa49d5cc42ae8ee1 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Sun, 2 Dec 2018 10:26:55 -0600 Subject: [PATCH 03/25] #20: Implement database side. #19: Implement database side. --- .../database/storage/db/Format.java | 45 +++---- .../database/storage/db/Game.java | 35 ++++-- .../database/storage/db/MatchEntry.java | 10 +- .../database/storage/db/MatchResult.java | 41 +++++-- .../database/storage/db/MatchResultType.java | 29 ++--- .../database/storage/db/Player.java | 5 +- .../database/storage/db/Record.java | 115 ++++++++++-------- .../database/storage/db/RecordPK.java | 92 ++++++++++++++ .../database/storage/db/Team.java | 25 ++-- .../database/storage/db/Tournament.java | 103 ++++++++-------- .../db/controller/GameJpaController.java | 67 ++++++++++ .../db/controller/PlayerJpaController.java | 16 +-- .../db/controller/RecordJpaController.java | 86 +++++++++++-- .../TournamentHasTeamJpaController.java | 4 +- .../storage/db/server/MatchService.java | 32 ++++- .../storage/db/server/PlayerService.java | 7 +- .../storage/db/server/RecordService.java | 2 +- 17 files changed, 504 insertions(+), 210 deletions(-) create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/RecordPK.java diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java index a4de235..2ad3499 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java @@ -36,9 +36,6 @@ }) public class Format implements Serializable { - private static final long serialVersionUID = 1L; - @EmbeddedId - protected FormatPK formatPK; @Basic(optional = false) @NotNull @Size(min = 1, max = 45) @@ -47,6 +44,9 @@ public class Format implements Serializable @Size(max = 255) @Column(name = "description") private String description; + private static final long serialVersionUID = 1L; + @EmbeddedId + protected FormatPK formatPK; @JoinColumn(name = "game_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) @@ -83,25 +83,6 @@ public void setFormatPK(FormatPK formatPK) this.formatPK = formatPK; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDescription() - { - return description; - } - - public void setDescription(String description) - { - this.description = description; - } public Game getGame() { @@ -151,4 +132,24 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.Format[ formatPK=" + formatPK + " ]"; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java index 4d6f340..451340a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java @@ -24,18 +24,18 @@ @Table(name = "game") @XmlRootElement @NamedQueries( -{ - @NamedQuery(name = "Game.findAll", query = "SELECT g FROM Game g"), - @NamedQuery(name = "Game.findById", - query = "SELECT g FROM Game g WHERE g.id = :id"), - @NamedQuery(name = "Game.findByName", - query = "SELECT g FROM Game g WHERE g.name = :name"), - @NamedQuery(name = "Game.findByDescription", - query = "SELECT g FROM Game g WHERE g.description = :description") -}) + { + @NamedQuery(name = "Game.findAll", query = "SELECT g FROM Game g"), + @NamedQuery(name = "Game.findById", + query = "SELECT g FROM Game g WHERE g.id = :id"), + @NamedQuery(name = "Game.findByName", + query = "SELECT g FROM Game g WHERE g.name = :name"), + @NamedQuery(name = "Game.findByDescription", + query = "SELECT g FROM Game g WHERE g.description = :description") + }) public class Game implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -6267533299417173163L; @Id @Basic(optional = false) @NotNull @@ -58,6 +58,8 @@ public class Game implements Serializable private String description; @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") private List formatList; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") + private List recordList; public Game() { @@ -126,7 +128,7 @@ public boolean equals(Object object) return false; } Game other = (Game) object; - return !((this.id == null && other.id != null) + return !((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))); } @@ -135,4 +137,15 @@ public String toString() { return "com.github.javydreamercsw.database.storage.db.Game[ id=" + id + " ]"; } + + @XmlTransient + public List getRecordList() + { + return recordList; + } + + public void setRecordList(List recordList) + { + this.recordList = recordList; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java index b6ac298..984bbad 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchEntry.java @@ -38,7 +38,7 @@ }) public class MatchEntry implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 3610712802330920081L; @EmbeddedId protected MatchEntryPK matchEntryPK; @Basic(optional = false) @@ -66,7 +66,7 @@ public class MatchEntry implements Serializable public MatchEntry() { - matchHasTeamList= new ArrayList<>(); + matchHasTeamList = new ArrayList<>(); } public MatchEntry(MatchEntryPK matchEntryPK) @@ -156,15 +156,15 @@ public boolean equals(Object object) return false; } MatchEntry other = (MatchEntry) object; - return !((this.matchEntryPK == null && other.matchEntryPK != null) - || (this.matchEntryPK != null + return !((this.matchEntryPK == null && other.matchEntryPK != null) + || (this.matchEntryPK != null && !this.matchEntryPK.equals(other.matchEntryPK))); } @Override public String toString() { - return "com.github.javydreamercsw.database.storage.db.MatchEntry[ matchEntryPK=" + return "com.github.javydreamercsw.database.storage.db.MatchEntry[ matchEntryPK=" + matchEntryPK + " ]"; } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResult.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResult.java index 704fb18..c9b5640 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResult.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResult.java @@ -31,6 +31,14 @@ }) public class MatchResult implements Serializable { + @Basic(optional = false) + @NotNull + @Column(name = "locked") + private boolean locked; + @Basic(optional = false) + @NotNull + @Column(name = "ranked") + private boolean ranked; private static final long serialVersionUID = 1L; @EmbeddedId protected MatchResultPK matchResultPK; @@ -40,10 +48,6 @@ public class MatchResult implements Serializable private MatchResultType matchResultType; @OneToMany(mappedBy = "matchResult") private List matchHasTeamList; - @Basic(optional = false) - @NotNull - @Column(name = "locked") - private boolean locked; public MatchResult() { @@ -94,15 +98,6 @@ public void setMatchHasTeamList(List matchHasTeamList) } - public boolean getLocked() - { - return locked; - } - - public void setLocked(boolean locked) - { - this.locked = locked; - } @Override public int hashCode() @@ -132,4 +127,24 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.MatchResult[ matchResultPK=" + matchResultPK + " ]"; } + + public boolean getLocked() + { + return locked; + } + + public void setLocked(boolean locked) + { + this.locked = locked; + } + + public boolean getRanked() + { + return ranked; + } + + public void setRanked(boolean ranked) + { + this.ranked = ranked; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResultType.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResultType.java index 3bed4a1..3b90bb8 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResultType.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/MatchResultType.java @@ -35,6 +35,11 @@ }) public class MatchResultType implements Serializable { + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 45) + @Column(name = "type") + private String type; private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @@ -48,11 +53,6 @@ public class MatchResultType implements Serializable initialValue = 1) @Column(name = "id") private Integer id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 45) - @Column(name = "type") - private String type; @OneToMany(cascade = CascadeType.ALL, mappedBy = "matchResultType") private List matchResultList; @@ -77,15 +77,6 @@ public void setId(Integer id) this.id = id; } - public String getType() - { - return type; - } - - public void setType(String type) - { - this.type = type; - } @XmlTransient public List getMatchResultList() @@ -125,4 +116,14 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.MatchResultType[ id=" + id + " ]"; } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Player.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Player.java index 6785a1f..586c848 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Player.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Player.java @@ -35,7 +35,7 @@ }) public class Player implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 3254339194105024707L; @Id @Basic(optional = false) @GeneratedValue(strategy = GenerationType.TABLE, generator = "PlayerGen") @@ -66,7 +66,8 @@ public class Player implements Serializable @JoinColumn(name = "player_id", referencedColumnName = "id") }, inverseJoinColumns = { - @JoinColumn(name = "record_id", referencedColumnName = "id") + @JoinColumn(name = "record_id", referencedColumnName = "id"), + @JoinColumn(name = "record_game_id", referencedColumnName = "game_id") }) @ManyToMany private List recordList; diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Record.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Record.java index 80503e5..fb4bc98 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Record.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Record.java @@ -6,17 +6,15 @@ import javax.persistence.Basic; import javax.persistence.Column; +import javax.persistence.EmbeddedId; import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; -import javax.persistence.TableGenerator; import javax.validation.constraints.NotNull; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; @@ -28,28 +26,18 @@ { @NamedQuery(name = "Record.findAll", query = "SELECT r FROM Record r"), @NamedQuery(name = "Record.findById", - query = "SELECT r FROM Record r WHERE r.id = :id"), + query = "SELECT r FROM Record r WHERE r.recordPK.id = :id"), @NamedQuery(name = "Record.findByWins", query = "SELECT r FROM Record r WHERE r.wins = :wins"), @NamedQuery(name = "Record.findByLoses", query = "SELECT r FROM Record r WHERE r.loses = :loses"), @NamedQuery(name = "Record.findByDraws", - query = "SELECT r FROM Record r WHERE r.draws = :draws") + query = "SELECT r FROM Record r WHERE r.draws = :draws"), + @NamedQuery(name = "Record.findByGameId", + query = "SELECT r FROM Record r WHERE r.recordPK.gameId = :gameId") }) public class Record implements Serializable { - private static final long serialVersionUID = 1L; - @Id - @Basic(optional = false) - @GeneratedValue(strategy = GenerationType.TABLE, generator = "RecordGen") - @TableGenerator(name = "RecordGen", table = "tm_id", - pkColumnName = "table_name", - valueColumnName = "last_id", - pkColumnValue = "record", - allocationSize = 1, - initialValue = 1) - @Column(name = "id") - private Integer id; @Basic(optional = false) @NotNull @Column(name = "wins") @@ -66,7 +54,8 @@ public class Record implements Serializable private List playerList; @JoinTable(name = "tournament_has_team_has_record", joinColumns = { - @JoinColumn(name = "record_id", referencedColumnName = "id") + @JoinColumn(name = "record_id", referencedColumnName = "id"), + @JoinColumn(name = "record_game_id", referencedColumnName = "game_id") }, inverseJoinColumns = { @JoinColumn(name = "tournament_has_team_tournament_id", @@ -76,6 +65,13 @@ public class Record implements Serializable }) @ManyToMany private List tournamentHasTeamList; + private static final long serialVersionUID = 1L; + @EmbeddedId + protected RecordPK recordPK; + @JoinColumn(name = "game_id", referencedColumnName = "id", insertable = false, + updatable = false) + @ManyToOne(optional = false) + private Game game; public Record() { @@ -91,14 +87,58 @@ public Record(int wins, int loses, int draws) playerList = new ArrayList<>(); } - public Integer getId() + public Record(int gameId) + { + this.recordPK = new RecordPK(gameId); + } + + public RecordPK getRecordPK() + { + return recordPK; + } + + public void setRecordPK(RecordPK recordPK) + { + this.recordPK = recordPK; + } + + + public Game getGame() + { + return game; + } + + public void setGame(Game game) { - return id; + this.game = game; } - public void setId(Integer id) + @Override + public int hashCode() { - this.id = id; + int hash = 0; + hash += (recordPK != null ? recordPK.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Record)) + { + return false; + } + Record other = (Record) object; + return !((this.recordPK == null && other.recordPK != null) + || (this.recordPK != null && !this.recordPK.equals(other.recordPK))); + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.Record[ recordPK=" + + recordPK + " ]"; } public int getWins() @@ -152,32 +192,5 @@ public void setTournamentHasTeamList(List tournamentHasTeamLi { this.tournamentHasTeamList = tournamentHasTeamList; } - - @Override - public int hashCode() - { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) - { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof Record)) - { - return false; - } - Record other = (Record) object; - return !((this.id == null && other.id != null) - || (this.id != null && !this.id.equals(other.id))); - } - - @Override - public String toString() - { - return "com.github.javydreamercsw.database.storage.db.Record[ id=" - + id + " ]"; - } + } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/RecordPK.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/RecordPK.java new file mode 100644 index 0000000..a23d531 --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/RecordPK.java @@ -0,0 +1,92 @@ +package com.github.javydreamercsw.database.storage.db; + +import java.io.Serializable; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.TableGenerator; +import javax.validation.constraints.NotNull; + +@Embeddable +public class RecordPK implements Serializable +{ + private static final long serialVersionUID = 2778418123591111690L; + @Basic(optional = false) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "RecordGen") + @TableGenerator(name = "RecordGen", table = "tm_id", + pkColumnName = "table_name", + valueColumnName = "last_id", + pkColumnValue = "record", + allocationSize = 1, + initialValue = 1) + @Column(name = "id") + private int id; + @Basic(optional = false) + @NotNull + @Column(name = "game_id") + private int gameId; + + public RecordPK() + { + } + + public RecordPK(int gameId) + { + this.gameId = gameId; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public int getGameId() + { + return gameId; + } + + public void setGameId(int gameId) + { + this.gameId = gameId; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (int) id; + hash += (int) gameId; + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof RecordPK)) + { + return false; + } + RecordPK other = (RecordPK) object; + if (this.id != other.id) + { + return false; + } + return this.gameId == other.gameId; + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.RecordPK[ id=" + id + + ", gameId=" + gameId + " ]"; + } +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java index 6853e85..bab914a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java @@ -34,6 +34,9 @@ }) public class Team implements Serializable { + @Size(max = 245) + @Column(name = "name") + private String name; private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @@ -46,9 +49,6 @@ public class Team implements Serializable initialValue = 1) @Column(name = "id") private Integer id; - @Size(max = 245) - @Column(name = "name") - private String name; @ManyToMany(mappedBy = "teamList") private List playerList; @OneToMany(cascade = CascadeType.ALL, mappedBy = "team") @@ -79,15 +79,6 @@ public void setId(Integer id) this.id = id; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } @XmlTransient public List getPlayerList() @@ -148,4 +139,14 @@ public String toString() { return "com.github.javydreamercsw.database.storage.db.Team[ id=" + id + " ]"; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java index 8f797bf..915de45 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java @@ -40,18 +40,6 @@ }) public class Tournament implements Serializable { - private static final long serialVersionUID = 1L; - @Id - @GeneratedValue(strategy = GenerationType.TABLE, generator = "TournamentGen") - @TableGenerator(name = "TournamentGen", table = "tm_id", - pkColumnName = "table_name", - valueColumnName = "last_id", - pkColumnValue = "tournament", - allocationSize = 1, - initialValue = 1) - @Basic(optional = false) - @Column(name = "id") - private Integer id; @Basic(optional = false) @NotNull @Size(min = 1, max = 245) @@ -69,6 +57,18 @@ public class Tournament implements Serializable @NotNull @Column(name = "lossPoints") private int lossPoints; + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TournamentGen") + @TableGenerator(name = "TournamentGen", table = "tm_id", + pkColumnName = "table_name", + valueColumnName = "last_id", + pkColumnValue = "tournament", + allocationSize = 1, + initialValue = 1) + @Basic(optional = false) + @Column(name = "id") + private Integer id; @OneToMany(cascade = CascadeType.ALL, mappedBy = "tournament") private List roundList; @OneToMany(cascade = CascadeType.ALL, mappedBy = "tournament") @@ -104,45 +104,6 @@ public void setId(Integer id) this.id = id; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public int getWinPoints() - { - return winPoints; - } - - public void setWinPoints(int winPoints) - { - this.winPoints = winPoints; - } - - public int getDrawPoints() - { - return drawPoints; - } - - public void setDrawPoints(int drawPoints) - { - this.drawPoints = drawPoints; - } - - public int getLossPoints() - { - return lossPoints; - } - - public void setLossPoints(int lossPoints) - { - this.lossPoints = lossPoints; - } @XmlTransient public List getRoundList() @@ -193,4 +154,44 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.Tournament[ id=" + id + " ]"; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public int getWinPoints() + { + return winPoints; + } + + public void setWinPoints(int winPoints) + { + this.winPoints = winPoints; + } + + public int getDrawPoints() + { + return drawPoints; + } + + public void setDrawPoints(int drawPoints) + { + this.drawPoints = drawPoints; + } + + public int getLossPoints() + { + return lossPoints; + } + + public void setLossPoints(int lossPoints) + { + this.lossPoints = lossPoints; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/GameJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/GameJpaController.java index 4ef8e3f..49d8620 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/GameJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/GameJpaController.java @@ -13,6 +13,7 @@ import com.github.javydreamercsw.database.storage.db.Format; import com.github.javydreamercsw.database.storage.db.Game; +import com.github.javydreamercsw.database.storage.db.Record; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.database.storage.db.server.AbstractController; @@ -31,6 +32,10 @@ public void create(Game game) { game.setFormatList(new ArrayList<>()); } + if (game.getRecordList() == null) + { + game.setRecordList(new ArrayList<>()); + } EntityManager em = null; try { @@ -43,6 +48,13 @@ public void create(Game game) attachedFormatList.add(formatListFormatToAttach); } game.setFormatList(attachedFormatList); + List attachedRecordList = new ArrayList<>(); + for (Record recordListRecordToAttach : game.getRecordList()) + { + recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getRecordPK()); + attachedRecordList.add(recordListRecordToAttach); + } + game.setRecordList(attachedRecordList); em.persist(game); for (Format formatListFormat : game.getFormatList()) { @@ -55,6 +67,17 @@ public void create(Game game) oldGameOfFormatListFormat = em.merge(oldGameOfFormatListFormat); } } + for (Record recordListRecord : game.getRecordList()) + { + Game oldGameOfRecordListRecord = recordListRecord.getGame(); + recordListRecord.setGame(game); + recordListRecord = em.merge(recordListRecord); + if (oldGameOfRecordListRecord != null) + { + oldGameOfRecordListRecord.getRecordList().remove(recordListRecord); + oldGameOfRecordListRecord = em.merge(oldGameOfRecordListRecord); + } + } em.getTransaction().commit(); } finally @@ -76,6 +99,8 @@ public void edit(Game game) throws IllegalOrphanException, NonexistentEntityExce Game persistentGame = em.find(Game.class, game.getId()); List formatListOld = persistentGame.getFormatList(); List formatListNew = game.getFormatList(); + List recordListOld = persistentGame.getRecordList(); + List recordListNew = game.getRecordList(); List illegalOrphanMessages = null; for (Format formatListOldFormat : formatListOld) { @@ -88,6 +113,17 @@ public void edit(Game game) throws IllegalOrphanException, NonexistentEntityExce illegalOrphanMessages.add("You must retain Format " + formatListOldFormat + " since its game field is not nullable."); } } + for (Record recordListOldRecord : recordListOld) + { + if (!recordListNew.contains(recordListOldRecord)) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("You must retain Record " + recordListOldRecord + " since its game field is not nullable."); + } + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); @@ -100,6 +136,14 @@ public void edit(Game game) throws IllegalOrphanException, NonexistentEntityExce } formatListNew = attachedFormatListNew; game.setFormatList(formatListNew); + List attachedRecordListNew = new ArrayList<>(); + for (Record recordListNewRecordToAttach : recordListNew) + { + recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getRecordPK()); + attachedRecordListNew.add(recordListNewRecordToAttach); + } + recordListNew = attachedRecordListNew; + game.setRecordList(recordListNew); game = em.merge(game); for (Format formatListNewFormat : formatListNew) { @@ -115,6 +159,20 @@ public void edit(Game game) throws IllegalOrphanException, NonexistentEntityExce } } } + for (Record recordListNewRecord : recordListNew) + { + if (!recordListOld.contains(recordListNewRecord)) + { + Game oldGameOfRecordListNewRecord = recordListNewRecord.getGame(); + recordListNewRecord.setGame(game); + recordListNewRecord = em.merge(recordListNewRecord); + if (oldGameOfRecordListNewRecord != null && !oldGameOfRecordListNewRecord.equals(game)) + { + oldGameOfRecordListNewRecord.getRecordList().remove(recordListNewRecord); + oldGameOfRecordListNewRecord = em.merge(oldGameOfRecordListNewRecord); + } + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -166,6 +224,15 @@ public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntity } illegalOrphanMessages.add("This Game (" + game + ") cannot be destroyed since the Format " + formatListOrphanCheckFormat + " in its formatList field has a non-nullable game field."); } + List recordListOrphanCheck = game.getRecordList(); + for (Record recordListOrphanCheckRecord : recordListOrphanCheck) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("This Game (" + game + ") cannot be destroyed since the Record " + recordListOrphanCheckRecord + " in its recordList field has a non-nullable game field."); + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java index 2aadb8b..3980bbd 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java @@ -30,28 +30,28 @@ public void create(Player player) { if (player.getTeamList() == null) { - player.setTeamList(new ArrayList<>()); + player.setTeamList(new ArrayList()); } if (player.getRecordList() == null) { - player.setRecordList(new ArrayList<>()); + player.setRecordList(new ArrayList()); } EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); - List attachedTeamList = new ArrayList<>(); + List attachedTeamList = new ArrayList(); for (Team teamListTeamToAttach : player.getTeamList()) { teamListTeamToAttach = em.getReference(teamListTeamToAttach.getClass(), teamListTeamToAttach.getId()); attachedTeamList.add(teamListTeamToAttach); } player.setTeamList(attachedTeamList); - List attachedRecordList = new ArrayList<>(); + List attachedRecordList = new ArrayList(); for (Record recordListRecordToAttach : player.getRecordList()) { - recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getId()); + recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getRecordPK()); attachedRecordList.add(recordListRecordToAttach); } player.setRecordList(attachedRecordList); @@ -89,7 +89,7 @@ public void edit(Player player) throws NonexistentEntityException, Exception List teamListNew = player.getTeamList(); List recordListOld = persistentPlayer.getRecordList(); List recordListNew = player.getRecordList(); - List attachedTeamListNew = new ArrayList<>(); + List attachedTeamListNew = new ArrayList(); for (Team teamListNewTeamToAttach : teamListNew) { teamListNewTeamToAttach = em.getReference(teamListNewTeamToAttach.getClass(), teamListNewTeamToAttach.getId()); @@ -97,10 +97,10 @@ public void edit(Player player) throws NonexistentEntityException, Exception } teamListNew = attachedTeamListNew; player.setTeamList(teamListNew); - List attachedRecordListNew = new ArrayList<>(); + List attachedRecordListNew = new ArrayList(); for (Record recordListNewRecordToAttach : recordListNew) { - recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getId()); + recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getRecordPK()); attachedRecordListNew.add(recordListNewRecordToAttach); } recordListNew = attachedRecordListNew; diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RecordJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RecordJpaController.java index 66ecc75..e5edf44 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RecordJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RecordJpaController.java @@ -1,3 +1,8 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ package com.github.javydreamercsw.database.storage.db.controller; import java.io.Serializable; @@ -11,23 +16,38 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; +import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Record; +import com.github.javydreamercsw.database.storage.db.RecordPK; import com.github.javydreamercsw.database.storage.db.TournamentHasTeam; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; -import com.github.javydreamercsw.database.storage.db.server.AbstractController; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.PreexistingEntityException; -public class RecordJpaController extends AbstractController implements Serializable +/** + * + * @author Javier Ortiz Bultron + */ +public class RecordJpaController implements Serializable { - private static final long serialVersionUID = -5982649688889824490L; - + private static final long serialVersionUID = 7601923040598485026L; public RecordJpaController(EntityManagerFactory emf) { - super(emf); + this.emf = emf; + } + private EntityManagerFactory emf = null; + + public EntityManager getEntityManager() + { + return emf.createEntityManager(); } - public void create(Record record) + public void create(Record record) throws PreexistingEntityException, Exception { + if (record.getRecordPK() == null) + { + record.setRecordPK(new RecordPK()); + } if (record.getPlayerList() == null) { record.setPlayerList(new ArrayList<>()); @@ -36,11 +56,18 @@ public void create(Record record) { record.setTournamentHasTeamList(new ArrayList<>()); } + record.getRecordPK().setGameId(record.getGame().getId()); EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); + Game game = record.getGame(); + if (game != null) + { + game = em.getReference(game.getClass(), game.getId()); + record.setGame(game); + } List attachedPlayerList = new ArrayList<>(); for (Player playerListPlayerToAttach : record.getPlayerList()) { @@ -56,6 +83,11 @@ public void create(Record record) } record.setTournamentHasTeamList(attachedTournamentHasTeamList); em.persist(record); + if (game != null) + { + game.getRecordList().add(record); + game = em.merge(game); + } for (Player playerListPlayer : record.getPlayerList()) { playerListPlayer.getRecordList().add(record); @@ -68,6 +100,14 @@ public void create(Record record) } em.getTransaction().commit(); } + catch (Exception ex) + { + if (findRecord(record.getRecordPK()) != null) + { + throw new PreexistingEntityException("Record " + record + " already exists.", ex); + } + throw ex; + } finally { if (em != null) @@ -79,16 +119,24 @@ public void create(Record record) public void edit(Record record) throws NonexistentEntityException, Exception { + record.getRecordPK().setGameId(record.getGame().getId()); EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); - Record persistentRecord = em.find(Record.class, record.getId()); + Record persistentRecord = em.find(Record.class, record.getRecordPK()); + Game gameOld = persistentRecord.getGame(); + Game gameNew = record.getGame(); List playerListOld = persistentRecord.getPlayerList(); List playerListNew = record.getPlayerList(); List tournamentHasTeamListOld = persistentRecord.getTournamentHasTeamList(); List tournamentHasTeamListNew = record.getTournamentHasTeamList(); + if (gameNew != null) + { + gameNew = em.getReference(gameNew.getClass(), gameNew.getId()); + record.setGame(gameNew); + } List attachedPlayerListNew = new ArrayList<>(); for (Player playerListNewPlayerToAttach : playerListNew) { @@ -106,6 +154,16 @@ public void edit(Record record) throws NonexistentEntityException, Exception tournamentHasTeamListNew = attachedTournamentHasTeamListNew; record.setTournamentHasTeamList(tournamentHasTeamListNew); record = em.merge(record); + if (gameOld != null && !gameOld.equals(gameNew)) + { + gameOld.getRecordList().remove(record); + gameOld = em.merge(gameOld); + } + if (gameNew != null && !gameNew.equals(gameOld)) + { + gameNew.getRecordList().add(record); + gameNew = em.merge(gameNew); + } for (Player playerListOldPlayer : playerListOld) { if (!playerListNew.contains(playerListOldPlayer)) @@ -145,7 +203,7 @@ record = em.merge(record); String msg = ex.getLocalizedMessage(); if (msg == null || msg.length() == 0) { - Integer id = record.getId(); + RecordPK id = record.getRecordPK(); if (findRecord(id) == null) { throw new NonexistentEntityException("The record with id " + id + " no longer exists."); @@ -162,7 +220,7 @@ record = em.merge(record); } } - public void destroy(Integer id) throws NonexistentEntityException + public void destroy(RecordPK id) throws NonexistentEntityException { EntityManager em = null; try @@ -173,12 +231,18 @@ public void destroy(Integer id) throws NonexistentEntityException try { record = em.getReference(Record.class, id); - record.getId(); + record.getRecordPK(); } catch (EntityNotFoundException enfe) { throw new NonexistentEntityException("The record with id " + id + " no longer exists.", enfe); } + Game game = record.getGame(); + if (game != null) + { + game.getRecordList().remove(record); + game = em.merge(game); + } List playerList = record.getPlayerList(); for (Player playerListPlayer : playerList) { @@ -234,7 +298,7 @@ private List findRecordEntities(boolean all, int maxResults, int firstRe } } - public Record findRecord(Integer id) + public Record findRecord(RecordPK id) { EntityManager em = getEntityManager(); try diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java index e338d6e..bcbfdcd 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java @@ -61,7 +61,7 @@ public void create(TournamentHasTeam tournamentHasTeam) throws PreexistingEntity List attachedRecordList = new ArrayList<>(); for (Record recordListRecordToAttach : tournamentHasTeam.getRecordList()) { - recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getId()); + recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getRecordPK()); attachedRecordList.add(recordListRecordToAttach); } tournamentHasTeam.setRecordList(attachedRecordList); @@ -129,7 +129,7 @@ public void edit(TournamentHasTeam tournamentHasTeam) throws NonexistentEntityEx List attachedRecordListNew = new ArrayList<>(); for (Record recordListNewRecordToAttach : recordListNew) { - recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getId()); + recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getRecordPK()); attachedRecordListNew.add(recordListNewRecordToAttach); } recordListNew = attachedRecordListNew; diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index e24fa7a..9c536ce 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -174,6 +174,35 @@ public boolean addTeam(MatchEntry match, Team team) throws Exception } match.getMatchHasTeamList().add(mht); + + // Make sure each team member has a record for this game. Add one otherwise. + team.getPlayerList().forEach(player -> + { + boolean found = false; + for (Record r : player.getRecordList()) + { + if (Objects.equals(r.getGame().getId(), match.getFormat().getGame().getId())) + { + found = true; + break; + } + } + if (!found) + { + try + { + Record record = new Record(); + record.getPlayerList().add(player); + record.setGame(match.getFormat().getGame()); + RecordService.getInstance().saveRecord(record); + player.getRecordList().add(record); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + } + }); return true; } @@ -264,10 +293,11 @@ public void setResult(MatchHasTeam mht, MatchResultType mrt) } /** - * Lock the match result. This is meant not to be undone as it calculates + * Lock the match result.This is meant not to be undone as it calculates * experience and update records which is dependent on when it happens. * * @param mr Match Result to lock. + * @throws java.lang.Exception */ public void lockMatchResult(MatchResult mr) throws Exception { diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java index 32845aa..639f3bb 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java @@ -159,7 +159,7 @@ public void deletePlayer(Player player) }); for (Record r : player.getRecordList()) { - rc.destroy(r.getId()); + rc.destroy(r.getRecordPK()); } pc.destroy(player.getId()); } @@ -197,11 +197,6 @@ public void savePlayer(Player player) throws Exception { pc.create(player); - Record record = new Record(); - record.getPlayerList().add(player); - RecordService.getInstance().saveRecord(record); - player.getRecordList().add(record); - //Create the single player's team Team alone = new Team(); alone.setName(player.getName()); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/RecordService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/RecordService.java index 6c28a8b..68ce2db 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/RecordService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/RecordService.java @@ -52,7 +52,7 @@ public static RecordService getInstance() public void saveRecord(Record record) throws Exception { - if (record.getId() == null) + if (record.getRecordPK() == null) { rc.create(record); } From 7f6b3dc3542db9c115d143f72da8a96f3ca41cb4 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Sun, 2 Dec 2018 17:31:46 -0600 Subject: [PATCH 04/25] #19: Implement UI side. --- .../storage/db/server/MatchService.java | 21 +++++- TournamentManagerWeb/pom.xml | 10 +-- .../views/matchlist/FormatLabelGenerator.java | 15 ++++ .../ui/views/matchlist/MatchEditorDialog.java | 72 +++++++++++++++---- .../manager/ui/views/matchlist/MatchList.java | 42 +++++++++-- 5 files changed, 134 insertions(+), 26 deletions(-) create mode 100644 TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index 9c536ce..fabd228 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -181,7 +181,8 @@ public boolean addTeam(MatchEntry match, Team team) throws Exception boolean found = false; for (Record r : player.getRecordList()) { - if (Objects.equals(r.getGame().getId(), match.getFormat().getGame().getId())) + if (Objects.equals(r.getGame().getId(), + match.getFormat().getGame().getId())) { found = true; break; @@ -338,4 +339,22 @@ public void lockMatchResult(MatchResult mr) throws Exception }); mrc.edit(mr); } + + /** + * Update a match result. + * + * @param mr Match result to update. + * @throws Exception If result doesn't exist. + */ + public void updateResult(MatchResult mr) throws Exception + { + if (mr.getMatchResultPK() != null) + { + mrc.edit(mr); + } + else + { + throw new Exception("Trying to update non existing result!"); + } + } } diff --git a/TournamentManagerWeb/pom.xml b/TournamentManagerWeb/pom.xml index dfdf78e..86d67cf 100755 --- a/TournamentManagerWeb/pom.xml +++ b/TournamentManagerWeb/pom.xml @@ -113,6 +113,11 @@ testng ${testng.version} test + + + ${project.groupId} + MTG + ${project.version} @@ -120,11 +125,6 @@ markdown-area 1.0.2 - - ${project.groupId} - MTG - ${project.version} - mysql diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java new file mode 100644 index 0000000..204a7ae --- /dev/null +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java @@ -0,0 +1,15 @@ +package com.github.javydreamercsw.tournament.manager.ui.views.matchlist; + +import com.github.javydreamercsw.database.storage.db.Format; +import com.vaadin.flow.component.ItemLabelGenerator; + +class FormatLabelGenerator implements ItemLabelGenerator +{ + private static final long serialVersionUID = -738603579674658479L; + + @Override + public String apply(Format f) + { + return f.getName(); + } +} diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java index c24be92..bc71273 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java @@ -36,7 +36,6 @@ import com.vaadin.flow.component.AbstractField.ComponentValueChangeEvent; import com.vaadin.flow.component.HasValue.ValueChangeEvent; import com.vaadin.flow.component.HasValue.ValueChangeListener; -import com.vaadin.flow.component.ItemLabelGenerator; import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.datepicker.DatePicker; @@ -48,20 +47,22 @@ /** * A dialog for editing {@link Format} objects. */ -public class MatchEditorDialog extends AbstractEditorDialog +public final class MatchEditorDialog extends AbstractEditorDialog { private static final long serialVersionUID = 2349638969280300323L; private final Grid grid = new Grid<>(); private final ComboBox cb = new ComboBox<>(); private final DatePicker datePicker = new DatePicker(); + private final Checkbox ranked = new Checkbox("Ranked"); public MatchEditorDialog(BiConsumer itemSaver, Consumer itemDeleter) { super("match", itemSaver, itemDeleter); - addTeams(); addFormat(); + addTeams(); addDate(); + addRanked(); validate(); } @@ -179,6 +180,60 @@ protected boolean isValid() && getCurrentItem().getMatchHasTeamList().size() >= 2; } + @Override + protected void validate() + { + if (getCurrentItem() != null) + { + getCurrentItem().setFormat(cb.getValue()); + } + grid.setVisible(cb.getValue() != null); + ranked.setVisible(cb.getValue() != null); + super.validate(); + } + + private void addRanked() + { + ranked.addClickListener(listener -> + { + getCurrentItem().getMatchHasTeamList().forEach((mht) -> + { + try + { + if (mht.getMatchResult() != null) + { + mht.getMatchResult().setRanked(ranked.getValue()); + MatchService.getInstance().updateResult(mht.getMatchResult()); + } + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + }); + }); + ranked.setValue(isMatchRanked()); + getFormLayout().add(ranked); + } + + private boolean isMatchRanked() + { + boolean isRanked = false; + if (getCurrentItem() == null) + { + return true; // Ranked by default + } + for (MatchHasTeam mht : getCurrentItem().getMatchHasTeamList()) + { + if (mht.getMatchResult() == null || !mht.getMatchResult().getRanked()) + { + isRanked = true; + break; + } + } + return isRanked; + } + private class TeamSelectionListener implements ValueChangeListener> { @@ -228,15 +283,4 @@ public void open() grid.setItems(teams); super.open(); } - - private class FormatLabelGenerator implements ItemLabelGenerator - { - private static final long serialVersionUID = -738603579674658479L; - - @Override - public String apply(Format f) - { - return f.getName(); - } - } } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java index c8f7281..c7ee77d 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchList.java @@ -24,11 +24,14 @@ import com.github.javydreamercsw.database.storage.db.MatchEntry; import com.github.javydreamercsw.database.storage.db.MatchHasTeam; import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.database.storage.db.server.MatchService; import com.github.javydreamercsw.tournament.manager.ui.MainLayout; import com.github.javydreamercsw.tournament.manager.ui.common.AbstractEditorDialog; import com.github.javydreamercsw.tournament.manager.ui.views.TMView; import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.checkbox.Checkbox; import com.vaadin.flow.component.dialog.Dialog; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid.SelectionMode; @@ -140,9 +143,11 @@ private void addContent() sb.append("TBD"); } return sb.toString(); - }).setHeader("Matches").setWidth("8em") + }).setHeader("Result").setWidth("9em") .setResizable(true); - grid.addColumn(new ComponentRenderer<>(this::resultButton)) + grid.addColumn(new ComponentRenderer<>(this::createRankedBox)) + .setWidth("1em").setHeader("Ranked"); + grid.addColumn(new ComponentRenderer<>(this::createResultButton)) .setWidth("4em"); grid.addColumn(new ComponentRenderer<>(this::createEditButton)) .setFlexGrow(0); @@ -151,6 +156,31 @@ private void addContent() container.add(header, grid); add(container); } + + private Checkbox createRankedBox(MatchEntry me){ + Checkbox ranked = new Checkbox(); + ranked.setValue(isMatchRanked(me)); + ranked.setEnabled(false); + return ranked; + } + + private boolean isMatchRanked(MatchEntry me) + { + boolean ranked = false; + if (me == null) + { + return true; // Ranked by default + } + for (MatchHasTeam mht : me.getMatchHasTeamList()) + { + if (mht.getMatchResult() == null || !mht.getMatchResult().getRanked()) + { + ranked = true; + break; + } + } + return ranked; + } private Button createEditButton(MatchEntry me) { @@ -163,7 +193,7 @@ private Button createEditButton(MatchEntry me) return edit; } - private Button resultButton(MatchEntry me) + private Button createResultButton(MatchEntry me) { Button result = new Button("Results", event -> { // List all the teams so results can be seen/set. @@ -180,7 +210,7 @@ private Button resultButton(MatchEntry me) result.setEnabled(isMatchLocked(me)); return result; } - + private boolean isMatchLocked(MatchEntry me) { boolean enable = false; @@ -194,7 +224,7 @@ private boolean isMatchLocked(MatchEntry me) } return enable || me.getMatchHasTeamList().isEmpty(); } - + @Override public void updateView() { @@ -280,7 +310,7 @@ private void deleteMatch(MatchEntry match) Position.BOTTOM_START); updateView(); } - catch (Exception ex) + catch (IllegalOrphanException | NonexistentEntityException ex) { Exceptions.printStackTrace(ex); } From ba348cc1c07a1a796a998b3a2266b6e9ab603875 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 3 Dec 2018 14:36:19 -0600 Subject: [PATCH 05/25] Add more test coverage. --- .../storage/db/server/DataBaseManager.java | 94 ++++++++++----- .../storage/db/server/GameService.java | 8 +- .../storage/db/server/TeamService.java | 16 +-- .../storage/db/server/TournamentService.java | 76 ++++-------- .../storage/db/AbstractServerTest.java | 16 ++- .../storage/db/server/BundleTest.java | 28 +++++ .../db/server/DataBaseManagerTest.java | 15 ++- .../storage/db/server/FormatServiceTest.java | 98 ++++++++------- .../storage/db/server/MatchServiceTest.java | 83 ++++++++++--- .../storage/db/server/TeamServiceTest.java | 26 +++- .../db/server/TournamentServiceTest.java | 114 ++++++++++++++++-- 11 files changed, 400 insertions(+), 174 deletions(-) create mode 100644 Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/BundleTest.java diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index 1f677b7..a837e3a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -59,15 +59,10 @@ public class DataBaseManager private static final Logger LOG = Logger.getLogger(DataBaseManager.class.getSimpleName()); private static boolean dbError = false; - private static DBState state; + private static DBState state = DBState.START_UP; public static final String JNDI_DATASOURCE_NAME = "java:comp/env/jdbc/TMDB"; - public DataBaseManager() - { - state = DBState.START_UP; - } - public static EntityManagerFactory getEntityManagerFactory() { if (emf == null) @@ -371,18 +366,6 @@ public static List namedQuery(String query) return namedQuery(query, null, false); } - /** - * Named query that will modify the database - * - * @param query query to execute - * @param parameters query parameters - */ - public static void namedUpdateQuery(String query, - Map parameters) - { - namedQuery(query, parameters, true); - } - /** * Named query (not for updates) * @@ -425,8 +408,17 @@ private static List namedQuery(String query, public static void close() { - getEntityManager().close(); - getEntityManagerFactory().close(); + if (em != null) + { + em.close(); + } + if (emf != null) + { + emf.close(); + } + //Set it to null so it's recreated with new Persistence Unit next time is requested. + emf = null; + em = null; } public static EntityTransaction getTransaction() @@ -434,16 +426,6 @@ public static EntityTransaction getTransaction() return getEntityManager().getTransaction(); } - /** - * Named query that will modify the database - * - * @param query query to execute - */ - public static void namedUpdateQuery(String query) - { - namedQuery(query, null, true); - } - public static List nativeQuery(String query) { EntityTransaction transaction = getEntityManager().getTransaction(); @@ -553,8 +535,7 @@ public static void loadDemoData() throws Exception ? "result.loss" : "result.win").get()); //Lock the results so records are updated. - match.getMatchHasTeamList().forEach(mht - -> + match.getMatchHasTeamList().forEach(mht -> { try { @@ -567,4 +548,53 @@ public static void loadDemoData() throws Exception }); } } + + /** + * Load stuff from the Lookup + */ + public static void load() + { + Lookup.getDefault().lookupAll(IGame.class).forEach(gameAPI -> + { + // Add game to DB if not there + Optional result + = GameService.getInstance().findGameByName(gameAPI.getName()); + + Game game; + if (result.isPresent()) + { + game = result.get(); + } + else + { + game = new Game(gameAPI.getName()); + GameService.getInstance().saveGame(game); + } + + //Load formats + gameAPI.gameFormats().forEach(format -> + { + // Check if it exists in the databse + Optional f + = FormatService.getInstance() + .findFormatForGame(gameAPI.getName(), format.getName()); + if (!f.isPresent()) + { + try + { + // Let's create it. + Format newFormat = new Format(); + newFormat.setName(format.getName()); + newFormat.setDescription(format.getDescription()); + newFormat.setGame(game); + FormatService.getInstance().saveFormat(newFormat); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + } + }); + }); + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/GameService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/GameService.java index 062c075..b5b53ba 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/GameService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/GameService.java @@ -1,6 +1,5 @@ package com.github.javydreamercsw.database.storage.db.server; -import java.util.HashMap; import java.util.List; import java.util.Optional; @@ -58,9 +57,6 @@ public static GameService getInstance() public Optional findGameByName(String name) { - HashMap parameters = new HashMap<>(); - parameters.put("name", name); - Game game = null; for (Game g : gc.findGameEntities()) { @@ -97,13 +93,13 @@ public void saveGame(Game game) Exceptions.printStackTrace(ex); } } - + @Override public List getAll() { return gc.findGameEntities(); } - + public void deleteGame(Game game) { try diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java index de6e246..fad11ce 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java @@ -24,7 +24,7 @@ public class TeamService extends Service private TeamService() { } - + /** * Helper class to initialize the singleton Service in a thread-safe way and * to keep the initialization ordering clear between the two services. See @@ -64,7 +64,7 @@ public List findTeams(String value) if (value.trim().isEmpty()) { - result.addAll(tc.findTeamEntities()); + result.addAll(getAll()); } else { @@ -149,7 +149,7 @@ public void addMembers(Team team, Player... players) { for (Player p : players) { - addMember(team, p, false); + addMember(team, p); } saveTeam(team); } @@ -159,18 +159,14 @@ public void addMembers(Team team, Player... players) * * @param team Team to add players to. * @param player Player to add. - * @param save Save team as part of this transaction. */ - public void addMember(Team team, Player player, boolean save) + public void addMember(Team team, Player player) { team.getPlayerList().add(player); player.getTeamList().add(team); - if (save) - { - saveTeam(team); - } + saveTeam(team); } - + @Override public List getAll() { diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java index e8a53c4..576dc2f 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java @@ -3,8 +3,6 @@ import java.util.ArrayList; import java.util.List; -import org.openide.util.Exceptions; - import com.github.javydreamercsw.database.storage.db.Round; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; @@ -67,7 +65,7 @@ public List findTournaments(String value) List result = new ArrayList<>(); tc.findTournamentEntities().forEach(tournament -> { - if (tournament.getName().toLowerCase().contains(value)) + if (tournament.getName().toLowerCase().contains(value.toLowerCase())) { result.add(tournament); } @@ -75,22 +73,12 @@ public List findTournaments(String value) return result; } - public void saveTournament(Tournament t) + public void saveTournament(Tournament t) throws NonexistentEntityException, + IllegalOrphanException, Exception { if (t.getId() != null && tc.findTournament(t.getId()) != null) { - try - { tc.edit(t); - } - catch (NonexistentEntityException ex) - { - Exceptions.printStackTrace(ex); - } - catch (Exception ex) - { - Exceptions.printStackTrace(ex); - } } else { @@ -98,27 +86,24 @@ public void saveTournament(Tournament t) } } - public void deleteTournament(Tournament t) + public void deleteTournament(Tournament t) throws IllegalOrphanException, + NonexistentEntityException { - try + for (Round round : t.getRoundList()) { - tc.destroy(t.getId()); + deleteRound(round); } - catch (IllegalOrphanException | NonexistentEntityException ex) + + for (TournamentHasTeam tht : t.getTournamentHasTeamList()) { - Exceptions.printStackTrace(ex); + deleteTeamFromTournament(tht); } + tc.destroy(t.getId()); } - public List findTournament(Integer id) + public Tournament findTournament(Integer id) { - List results = new ArrayList<>(); - Tournament t = tc.findTournament(id); - if (t != null) - { - results.add(t); - } - return results; + return tc.findTournament(id); } /** @@ -140,25 +125,12 @@ public void addTeams(Tournament t, List teams) throws Exception * @param teams Teams to add * @throws Exception if there's an error adding teams. */ - public void addTeams(Tournament t, Team... teams) throws Exception + public void addTeams(Tournament t, Team... teams) throws Exception { for (Team team : teams) { - addTeam(t, team, false); + addTeam(t, team); } - saveTournament(t); - } - - /** - * Add team to the tournament. - * - * @param t Tournament - * @param team Team to add - * @throws Exception if there's an error adding team. - */ - public void addTeam(Tournament t, Team team) throws Exception - { - addTeam(t, team, true); } /** @@ -166,20 +138,18 @@ public void addTeam(Tournament t, Team team) throws Exception * * @param t Tournament * @param team Team to add - * @param save Save the tournament as part of this transaction. + * @throws IllegalOrphanException if an orphan is left * @throws Exception if there's an error adding team. */ - public void addTeam(Tournament t, Team team, boolean save) throws Exception + public void addTeam(Tournament t, Team team) throws IllegalOrphanException, + Exception { TournamentHasTeam tht = new TournamentHasTeam(); tht.setTeam(team); tht.setTournament(t); - t.getTournamentHasTeamList().add(tht); thtc.create(tht); - if (save) - { - saveTournament(t); - } + t.getTournamentHasTeamList().add(tht); + saveTournament(t); } /** @@ -229,4 +199,10 @@ public List getAll() { return tc.findTournamentEntities(); } + + public void deleteRound(Round round) throws IllegalOrphanException, + NonexistentEntityException + { + rc.destroy(round.getRoundPK()); + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/AbstractServerTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/AbstractServerTest.java index 4a909be..4e5010a 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/AbstractServerTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/AbstractServerTest.java @@ -1,5 +1,6 @@ package com.github.javydreamercsw.database.storage.db; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; @@ -10,6 +11,7 @@ import com.github.javydreamercsw.database.storage.db.server.MatchService; import com.github.javydreamercsw.database.storage.db.server.PlayerService; import com.github.javydreamercsw.database.storage.db.server.TeamService; +import com.github.javydreamercsw.database.storage.db.server.TournamentService; /** * @@ -23,13 +25,25 @@ public AbstractServerTest() } @BeforeClass - public void setup() throws NonexistentEntityException, IllegalOrphanException + public void setup() throws NonexistentEntityException, IllegalOrphanException, + Exception { DataBaseManager.setPersistenceUnitName("TestTMPU"); + cleanDB(); + DataBaseManager.load(); + } + + @AfterClass + protected void cleanDB() throws NonexistentEntityException, IllegalOrphanException + { for (MatchEntry match : MatchService.getInstance().getAll()) { MatchService.getInstance().deleteMatch(match); } + for (Tournament tournament : TournamentService.getInstance().getAll()) + { + TournamentService.getInstance().deleteTournament(tournament); + } TeamService.getInstance().getAll().forEach(team -> TeamService.getInstance().deleteTeam(team)); PlayerService.getInstance().getAll().forEach(player diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/BundleTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/BundleTest.java new file mode 100644 index 0000000..46f3ccf --- /dev/null +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/BundleTest.java @@ -0,0 +1,28 @@ +package com.github.javydreamercsw.database.storage.db.server; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.fail; + +import java.util.MissingResourceException; + +import org.openide.util.NbBundle; +import org.testng.annotations.Test; + +public class BundleTest +{ + @Test + public void testBundle() + { + assertNotNull(NbBundle.getMessage(DataBaseManager.class, "message.db.locked")); + + try + { + NbBundle.getMessage(DataBaseManager.class, "dummy"); + fail("Expected MissingResourceException!"); + } + catch (MissingResourceException ex) + { + // Expected + } + } +} diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java index d4a3a75..0f7f102 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java @@ -5,12 +5,16 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.openide.util.Lookup; import org.testng.annotations.Test; import com.github.javydreamercsw.database.storage.db.AbstractServerTest; import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.tournament.manager.api.IGame; public class DataBaseManagerTest extends AbstractServerTest { @@ -36,7 +40,7 @@ public void testLoadDemoData() throws Exception assertEquals(me.getMatchHasTeamList().size(), 2); assertNotNull(me.getFormat()); }); - + List results = DataBaseManager.namedQuery("MatchEntry.findAll"); assertTrue(results.size() > 0); @@ -47,4 +51,13 @@ public void testLoadDemoData() throws Exception assertNotNull(m.getFormat()); }); } + + @Test + public void testNamedQuery() + { + Map parameters = new HashMap<>(); + parameters.put("name", Lookup.getDefault().lookup(IGame.class).getName()); + + assertFalse(DataBaseManager.namedQuery("Game.findByName", parameters).isEmpty()); + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/FormatServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/FormatServiceTest.java index d23a613..bc7ea72 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/FormatServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/FormatServiceTest.java @@ -1,14 +1,11 @@ package com.github.javydreamercsw.database.storage.db.server; +import static org.testng.Assert.*; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.fail; +import java.util.List; +import java.util.Optional; -import java.util.stream.Stream; - -import org.openide.util.Exceptions; +import org.openide.util.Lookup; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -17,39 +14,20 @@ import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.api.IGame; public class FormatServiceTest extends AbstractServerTest { - private Game game = new Game("Test"); + private Game game; @BeforeClass @Override - public void setup() throws NonexistentEntityException, IllegalOrphanException + public void setup() throws NonexistentEntityException, IllegalOrphanException, + Exception { super.setup(); - GameService.getInstance().saveGame(game); - Stream.of("Commander", - "Beatdown", - "Legacy", - "Standard", - "Draft") - .forEach(name -> - { - if (!FormatService.getInstance().findFormatByName(name).isPresent()) - { - try - { - Format format = new Format(name); - format.setGame(game); - FormatService.getInstance().saveFormat(format); - } - catch (Exception ex) - { - Exceptions.printStackTrace(ex); - fail(); - } - } - }); + game = GameService.getInstance().findGameByName(Lookup.getDefault() + .lookup(IGame.class).getName()).get(); } /** @@ -58,8 +36,7 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException @Test public void testFindFormats() { - System.out.println("findFormats"); - assertFalse(FormatService.getInstance().findFormats("").isEmpty()); + assertFalse(FormatService.getInstance().getAll().isEmpty()); } /** @@ -68,10 +45,10 @@ public void testFindFormats() @Test public void testFindFormatByName() { - System.out.println("findFormatByName"); - assertEquals(1, FormatService.getInstance().findFormats("Commander").size()); - - assertEquals(0, FormatService.getInstance().findFormats("Commander2").size()); + assertEquals(1, FormatService.getInstance() + .findFormats(game.getFormatList().get(0).getName()).size()); + assertEquals(0, FormatService.getInstance() + .findFormats(game.getFormatList().get(0).getName() + "2").size()); } /** @@ -80,12 +57,12 @@ public void testFindFormatByName() @Test public void testFindFormatOrThrow() { - System.out.println("findFormatOrThrow"); - assertNotNull(FormatService.getInstance().findFormatOrThrow("Commander")); - + assertNotNull(FormatService.getInstance() + .findFormatOrThrow(game.getFormatList().get(0).getName())); try { - FormatService.getInstance().findFormatOrThrow("Commander2"); + FormatService.getInstance() + .findFormatOrThrow(game.getFormatList().get(0).getName() + "2"); fail("Expected exception!"); } catch (IllegalStateException ex) @@ -100,10 +77,10 @@ public void testFindFormatOrThrow() @Test public void testFindFormatById() { - System.out.println("findCategoryById"); assertNotNull(FormatService.getInstance() .findFormatById(FormatService.getInstance() - .findFormatByName("Commander").get().getFormatPK())); + .findFormatByName(game.getFormatList().get(0).getName()).get() + .getFormatPK())); } /** @@ -114,7 +91,6 @@ public void testFindFormatById() @Test public void testDeleteFormat() throws Exception { - System.out.println("deleteFormat"); Format format = new Format("test"); format.setGame(game); assertEquals(FormatService.getInstance().findFormats("test").size(), 0); @@ -124,4 +100,36 @@ public void testDeleteFormat() throws Exception .findFormatByName(format.getName()).get()); assertEquals(FormatService.getInstance().findFormats("test").size(), 0); } + + /** + * Test of findFormatForGame method, of class FormatService. + */ + @Test + public void testFindFormatForGame() + { + Optional result = FormatService.getInstance().findFormatForGame(game.getName(), + game.getFormatList().get(0).getName()); + assertTrue(result.isPresent()); + + result = FormatService.getInstance().findFormatForGame(game.getName(), + game.getFormatList().get(0).getName() + "x"); + assertFalse(result.isPresent()); + + result = FormatService.getInstance().findFormatForGame(game.getName() + "x", + game.getFormatList().get(0).getName()); + assertFalse(result.isPresent()); + } + + /** + * Test of findFormatByGame method, of class FormatService. + */ + @Test + public void testFindFormatByGame() + { + List result = FormatService.getInstance().findFormatByGame(game); + assertFalse(result.isEmpty()); + + result = FormatService.getInstance().findFormatByGame(game.getName() + "2"); + assertTrue(result.isEmpty()); + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index ea3b8fa..60c5173 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -6,10 +6,11 @@ import java.util.Random; import org.openide.util.Exceptions; +import org.openide.util.Lookup; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.github.javydreamercsw.database.storage.db.AbstractServerTest; -import com.github.javydreamercsw.database.storage.db.Format; import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.MatchEntry; import com.github.javydreamercsw.database.storage.db.MatchHasTeam; @@ -17,6 +18,9 @@ import com.github.javydreamercsw.database.storage.db.MatchResultType; import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.api.IGame; import com.github.javydreamercsw.tournament.manager.api.TournamentException; /** @@ -25,6 +29,30 @@ */ public class MatchServiceTest extends AbstractServerTest { + private Game game; + private MatchEntry me; + + @BeforeClass + @Override + public void setup() throws NonexistentEntityException, IllegalOrphanException, + Exception + { + super.setup(); + game = GameService.getInstance().findGameByName(Lookup.getDefault() + .lookup(IGame.class).getName()).get(); + Tournament t = new Tournament("Test 1"); + TournamentService.getInstance().saveTournament(t); + TournamentService.getInstance().addRound(t); + + GameService.getInstance().saveGame(game); + + me = new MatchEntry(); + me.setFormat(game.getFormatList().get(0)); + me.setRound(t.getRoundList().get(0)); + + MatchService.getInstance().saveMatch(me); + } + /** * Test of write2DB method, of class MatchServer. * @@ -38,19 +66,6 @@ public void testMatchService() throws TournamentException, Exception TournamentService.getInstance().saveTournament(t); TournamentService.getInstance().addRound(t); - Game game = new Game("Test Game"); - GameService.getInstance().saveGame(game); - - Format format = new Format("Default"); - format.setGame(game); - FormatService.getInstance().saveFormat(format); - - MatchEntry me = new MatchEntry(); - me.setFormat(format); - me.setRound(t.getRoundList().get(0)); - - MatchService.getInstance().saveMatch(me); - MatchEntry match = MatchService.getInstance().findMatch(me.getMatchEntryPK()); assertNotNull(me.getFormat()); @@ -143,5 +158,45 @@ public void testMatchService() throws TournamentException, Exception + p.getRecordList().get(0).getLoses() + p.getRecordList().get(0).getWins() > 0); }); + + MatchService.getInstance().saveMatch(me); + + for(MatchHasTeam mht:me.getMatchHasTeamList()) + { + MatchResult mr = mht.getMatchResult(); + assertNotNull(mr); + mr.setLocked(true); + MatchService.getInstance().updateResult(mr); + } + + TeamService.getInstance().getAll().forEach(team -> + { + try + { + MatchService.getInstance().removeTeam(me, team); + } + catch (NonexistentEntityException ex) + { + Exceptions.printStackTrace(ex); + fail(); + } + }); + + assertTrue(MatchService.getInstance().findMatch(me.getMatchEntryPK()) + .getMatchHasTeamList().isEmpty()); + } + + @Test + public void testFindMatchesWithFormat() + { + assertEquals(MatchService.getInstance().findMatchesWithFormat("").size(), + game.getFormatList().size()); + + assertEquals(MatchService.getInstance() + .findMatchesWithFormat(game.getFormatList().get(0).getName()).size(), 1); + + assertTrue(MatchService.getInstance() + .findMatchesWithFormat(game.getFormatList().get(0).getName() + "x") + .isEmpty()); } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TeamServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TeamServiceTest.java index f171141..812f780 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TeamServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TeamServiceTest.java @@ -2,8 +2,12 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; import static org.testng.Assert.fail; +import java.util.ArrayList; +import java.util.List; + import org.openide.util.Exceptions; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -43,9 +47,9 @@ public void setup() @Test public void testFindTeams() { - System.out.println("findTeams"); assertEquals(TeamService.getInstance().findTeams("Player 1").size(), 1); assertEquals(TeamService.getInstance().findTeams("Player 3").size(), 0); + assertEquals(TeamService.getInstance().findTeams("").size(), 2); } /** @@ -54,7 +58,6 @@ public void testFindTeams() @Test public void testFindTeam() { - System.out.println("findTeam"); assertNotNull(TeamService.getInstance().findTeam(TeamService.getInstance() .findTeams("Player 1").get(0).getId())); } @@ -65,14 +68,25 @@ public void testFindTeam() @Test public void testSaveTeam() { - System.out.println("saveTeam"); Team team = new Team(); team.setName("The Players"); TeamService.getInstance().saveTeam(team); assertNotNull(team.getId()); - TeamService.getInstance().addMembers(team, - PlayerService.getInstance().findPlayerByName("Player 1").get(), - PlayerService.getInstance().findPlayerByName("Player 2").get()); + assertEquals(TeamService.getInstance().findTeam(team.getId()) + .getPlayerList().size(), 0); + List players = new ArrayList<>(); + + players.add(PlayerService.getInstance().findPlayerByName("Player 1").get()); + players.add(PlayerService.getInstance().findPlayerByName("Player 2").get()); + + TeamService.getInstance().addMembers(team,players); + + assertEquals(TeamService.getInstance().findTeam(team.getId()) + .getPlayerList().size(), 2); + + TeamService.getInstance().deleteTeam(team); + + assertNull(TeamService.getInstance().findTeam(team.getId())); } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java index e788dc1..e9949c3 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java @@ -1,13 +1,23 @@ package com.github.javydreamercsw.database.storage.db.server; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.fail; +import java.util.ArrayList; +import java.util.List; + +import org.openide.util.Exceptions; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.github.javydreamercsw.database.storage.db.AbstractServerTest; import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; /** * @@ -15,17 +25,28 @@ */ public class TournamentServiceTest extends AbstractServerTest { - /** - * Test of write2DB method, of class TournamentHasTeamServer. - * - * @throws java.lang.Exception - */ - @Test - public void testWrite2DB() throws Exception + private Tournament t; + + @BeforeClass + @Override + public void setup() throws NonexistentEntityException, IllegalOrphanException { - Tournament t = new Tournament("Test"); - TournamentService.getInstance().saveTournament(t); + try + { + super.setup(); + t = new Tournament("Test"); + TournamentService.getInstance().saveTournament(t); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + fail(); + } + } + @Test + public void testAddTeam() throws Exception + { Player player = new Player("Player 1"); PlayerService.getInstance().savePlayer(player); @@ -40,5 +61,80 @@ public void testWrite2DB() throws Exception TournamentService.getInstance().addTeam(t, team); assertEquals(t.getTournamentHasTeamList().size(), 1); + + TournamentService.getInstance().deleteTeamFromTournament(t + .getTournamentHasTeamList().get(0)); + } + + @Test + public void testFindTournament() + { + assertNotNull(TournamentService.getInstance().findTournament(t.getId())); + assertNull(TournamentService.getInstance().findTournament(2_000)); + } + + @Test + public void testFindTournaments() + { + assertEquals(TournamentService.getInstance().findTournaments(t.getName()) + .size(), 1); + assertEquals(TournamentService.getInstance().findTournaments(t.getName() + + "x").size(), 0); + } + + @Test + public void testSaveAndDelete() throws IllegalOrphanException, + NonexistentEntityException, Exception + { + Tournament t2 = new Tournament("Test 2"); + assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) + .size(), 0); + + TournamentService.getInstance().saveTournament(t2); + + assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) + .size(), 1); + + TournamentService.getInstance().deleteTournament(t2); + + assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) + .size(), 0); + } + + @Test + public void testAddTeams() throws Exception + { + Tournament tournament = new Tournament("Add Team"); + TournamentService.getInstance().saveTournament(tournament); + + Player player3 = new Player("Player 3"); + PlayerService.getInstance().savePlayer(player3); + + Player player4 = new Player("Player 4"); + PlayerService.getInstance().savePlayer(player4); + + Team team2 = new Team("Test Team 2"); + team2.getPlayerList().add(player3); + team2.getPlayerList().add(player4); + TeamService.getInstance().saveTeam(team2); + Player player5 = new Player("Player 5"); + PlayerService.getInstance().savePlayer(player5); + + Player player6 = new Player("Player 6"); + PlayerService.getInstance().savePlayer(player6); + + Team team3 = new Team("Test Team"); + team3.getPlayerList().add(player3); + team3.getPlayerList().add(player5); + TeamService.getInstance().saveTeam(team3); + + List teams= new ArrayList<>(); + teams.add(team3); + teams.add(team2); + + TournamentService.getInstance().addTeams(tournament, teams); + + assertEquals(TournamentService.getInstance().findTournament(tournament.getId()) + .getTournamentHasTeamList().size(), 2); } } From a946b9a2367e3c61fa21cd16e03b7db12e00955d Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 3 Dec 2018 14:40:36 -0600 Subject: [PATCH 06/25] Fix due to changes in database classes. --- .gitignore | 3 +- .../views/tournamentlist/TournamentList.java | 15 +++--- .../manager/ui/views/welcome/Welcome.java | 48 +------------------ 3 files changed, 11 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index fe558a3..a7a1fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /Database-Storage/target/ /TrueSkill/target/ /TournamentManagerWeb/target/ -/MTG/target/ \ No newline at end of file +/MTG/target/ +/target/ \ No newline at end of file diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java index be5d5d5..629fccb 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java @@ -20,6 +20,8 @@ import org.openide.util.Exceptions; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.database.storage.db.server.TournamentService; import com.github.javydreamercsw.tournament.manager.ui.MainLayout; import com.github.javydreamercsw.tournament.manager.ui.common.AbstractEditorDialog; @@ -89,12 +91,12 @@ private void addSearchBar() viewToolbar.add(searchField, newButton); add(viewToolbar); } - + private String getRoundCount(Tournament t) { return Integer.toString(t.getRoundList().size()); } - + private String getTeamCount(Tournament t) { return Integer.toString(t.getTournamentHasTeamList().size()); @@ -153,7 +155,7 @@ private void saveTournament(Tournament t, try { TournamentService.getInstance().saveTournament(t); - + Notification.show( "Tournament successfully " + operation.getNameInText() + "ed.", 3000, Position.BOTTOM_START); @@ -167,10 +169,7 @@ private void saveTournament(Tournament t, private void deleteTournament(Tournament t) { - List matchesInCategory = TournamentService.getInstance() - .findTournament(t.getId()); - - if (matchesInCategory.isEmpty()) + if (TournamentService.getInstance().findTournament(t.getId()) != null) { try { @@ -180,7 +179,7 @@ private void deleteTournament(Tournament t) Position.BOTTOM_START); updateView(); } - catch (Exception ex) + catch (IllegalOrphanException | NonexistentEntityException ex) { Exceptions.printStackTrace(ex); } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java index 6071cc1..bb4c638 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; import javax.naming.InitialContext; import javax.naming.NamingException; @@ -11,11 +10,7 @@ import org.openide.util.Lookup; import org.vaadin.maxime.MarkdownArea; -import com.github.javydreamercsw.database.storage.db.Format; -import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.server.DataBaseManager; -import com.github.javydreamercsw.database.storage.db.server.FormatService; -import com.github.javydreamercsw.database.storage.db.server.GameService; import com.github.javydreamercsw.database.storage.db.server.PlayerService; import com.github.javydreamercsw.tournament.manager.api.IGame; import com.github.javydreamercsw.tournament.manager.ui.MainLayout; @@ -49,6 +44,8 @@ public class Welcome extends TMView DataBaseManager.setPersistenceUnitName(JNDIDB); demo = (Boolean) context .lookup("java:comp/env/tm/demo"); + + DataBaseManager.load(); } catch (NamingException ex) { @@ -75,47 +72,6 @@ public Welcome() public void valueChanged(ValueChangeEvent e) { IGame gameAPI = cb.getValue(); - // Update everything to the new game. - - // Add game to DB if not there - Optional result - = GameService.getInstance().findGameByName(gameAPI.getName()); - - Game game; - if (result.isPresent()) - { - game = result.get(); - } - else - { - game = new Game(gameAPI.getName()); - GameService.getInstance().saveGame(game); - } - - //Load formats - gameAPI.gameFormats().forEach(format -> - { - // Check if it exists in the databse - Optional f - = FormatService.getInstance() - .findFormatForGame(gameAPI.getName(), format.getName()); - if (!f.isPresent()) - { - try - { - // Let's create it. - Format newFormat = new Format(); - newFormat.setName(format.getName()); - newFormat.setDescription(format.getDescription()); - newFormat.setGame(game); - FormatService.getInstance().saveFormat(newFormat); - } - catch (Exception ex) - { - Exceptions.printStackTrace(ex); - } - } - }); saveValue(CURRENT_GAME, gameAPI.getName()); // Check if it's configured for demo From d6cc35135a96c82746ab2b9475478e3d2252c344 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 3 Dec 2018 14:40:55 -0600 Subject: [PATCH 07/25] Include JaCoCo coverage. --- pom.xml | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index f0b6d94..cc04d39 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,31 @@ maven-resources-plugin 3.1.0 + + org.apache.maven.plugins + maven-site-plugin + 3.7.1 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.0.0 + + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.1 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.1 + @@ -39,19 +64,89 @@ - org.codehaus.mojo - cobertura-maven-plugin - 2.7 + org.apache.maven.plugins + maven-site-plugin + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + org.jacoco + jacoco-maven-plugin + + + + pre-unit-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + ${project.reporting.outputDirectory}/jacoco-ut + + + + + + org.apache.maven.plugins + maven-surefire-plugin - - html - xml - - + + ${surefireArgLine} + + ${skipTests} + + + **/IT*.java + + + + + + org.jacoco + jacoco-maven-plugin + + + + + report + + + + + + + TMCore Elimination-Tournament From 0f3dbe804c4cde71d6bd5985c7283a3dfdad822b Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 3 Dec 2018 16:24:36 -0600 Subject: [PATCH 08/25] Ignore test coverage on generated code. --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index cc04d39..e62164e 100644 --- a/pom.xml +++ b/pom.xml @@ -112,6 +112,12 @@ + + + **/controller/**/* + **/db/* + + org.apache.maven.plugins From ab3974da73ca8c311bee10197536584db04b9814 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 3 Dec 2018 16:43:05 -0600 Subject: [PATCH 09/25] #6: Add tournament format. --- Database-Storage/DB.mwb | Bin 25129 -> 27910 bytes Database-Storage/DB.mwb.bak | Bin 24991 -> 27296 bytes .../database/storage/db/Round.java | 13 +- .../database/storage/db/Tournament.java | 171 ++++++------ .../database/storage/db/TournamentFormat.java | 141 ++++++++++ .../storage/db/TournamentHasTeam.java | 14 +- .../database/storage/db/TournamentPK.java | 93 +++++++ .../db/controller/PlayerJpaController.java | 12 +- .../db/controller/RoundJpaController.java | 10 +- .../TournamentFormatJpaController.java | 257 ++++++++++++++++++ .../TournamentHasTeamJpaController.java | 10 +- .../controller/TournamentJpaController.java | 164 +++++++---- .../storage/db/server/DataBaseManager.java | 26 +- .../storage/db/server/TournamentService.java | 41 ++- .../main/resources/META-INF/persistence.xml | 3 + .../storage/db/server/MatchServiceTest.java | 7 + .../db/server/TestTournamentFormat.java | 53 ++++ .../db/server/TournamentServiceTest.java | 28 +- .../ui/views/matchlist/MatchEditorDialog.java | 11 +- .../TournamentEditorDialog.java | 72 ++++- .../TournamentFormatLabelGenerator.java | 15 + .../views/tournamentlist/TournamentList.java | 9 +- 22 files changed, 961 insertions(+), 189 deletions(-) create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentPK.java create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentFormatJpaController.java create mode 100644 Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java create mode 100644 TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index 9371af1ef6f8f4c2c8e3baeee8f12b8b9424ebe5..0da7646b07e998cd41f39323c3d2601c688af369 100644 GIT binary patch literal 27910 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 S34?T;JX}9n{L|hH<^KWU3_Ak= literal 25129 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 ?z#~LBt5Tm_>l_qCzZ+U~DESqsMU$*%tRV_ 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 roundList; + @JoinColumn(name = "tournament_format_id", referencedColumnName = "id", + insertable = false, updatable = false) + @ManyToOne(optional = false) + private TournamentFormat tournamentFormat; @OneToMany(cascade = CascadeType.ALL, mappedBy = "tournament") private List tournamentHasTeamList; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "tournament") + private List roundList; public Tournament() { @@ -94,104 +90,119 @@ public Tournament(String name, int winPoints, int drawPoints, int lossPoints) tournamentHasTeamList = new ArrayList<>(); } - public Integer getId() + public Tournament(int tournamentFormatId) { - return id; + this.tournamentPK = new TournamentPK(tournamentFormatId); } - public void setId(Integer id) + public TournamentPK getTournamentPK() { - this.id = id; + return tournamentPK; } + public void setTournamentPK(TournamentPK tournamentPK) + { + this.tournamentPK = tournamentPK; + } - @XmlTransient - public List getRoundList() + public String getName() { - return roundList; + return name; } - public void setRoundList(List roundList) + public void setName(String name) { - this.roundList = roundList; + this.name = name; } - @XmlTransient - public List getTournamentHasTeamList() + public int getWinPoints() { - return tournamentHasTeamList; + return winPoints; } - public void setTournamentHasTeamList(List tournamentHasTeamList) + public void setWinPoints(int winPoints) { - this.tournamentHasTeamList = tournamentHasTeamList; + this.winPoints = winPoints; } - @Override - public int hashCode() + public int getDrawPoints() { - int hash = 0; - hash += (id != null ? id.hashCode() : 0); - return hash; + return drawPoints; } - @Override - public boolean equals(Object object) + public void setDrawPoints(int drawPoints) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof Tournament)) - { - return false; - } - Tournament other = (Tournament) object; - return !((this.id == null && other.id != null) - || (this.id != null && !this.id.equals(other.id))); + this.drawPoints = drawPoints; } - @Override - public String toString() + public int getLossPoints() + { + return lossPoints; + } + + public void setLossPoints(int lossPoints) { - return "com.github.javydreamercsw.database.storage.db.Tournament[ id=" - + id + " ]"; + this.lossPoints = lossPoints; } - public String getName() + public TournamentFormat getTournamentFormat() { - return name; + return tournamentFormat; } - public void setName(String name) + public void setTournamentFormat(TournamentFormat tournamentFormat) { - this.name = name; + this.tournamentFormat = tournamentFormat; } - public int getWinPoints() + @XmlTransient + public List getTournamentHasTeamList() { - return winPoints; + return tournamentHasTeamList; } - public void setWinPoints(int winPoints) + public void setTournamentHasTeamList(List tournamentHasTeamList) { - this.winPoints = winPoints; + this.tournamentHasTeamList = tournamentHasTeamList; } - public int getDrawPoints() + @XmlTransient + public List getRoundList() { - return drawPoints; + return roundList; } - public void setDrawPoints(int drawPoints) + public void setRoundList(List roundList) { - this.drawPoints = drawPoints; + this.roundList = roundList; } - public int getLossPoints() + @Override + public int hashCode() { - return lossPoints; + int hash = 0; + hash += (tournamentPK != null ? tournamentPK.hashCode() : 0); + return hash; } - public void setLossPoints(int lossPoints) + @Override + public boolean equals(Object object) { - this.lossPoints = lossPoints; + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Tournament)) + { + return false; + } + Tournament other = (Tournament) object; + return !((this.tournamentPK == null && other.tournamentPK != null) + || (this.tournamentPK != null + && !this.tournamentPK.equals(other.tournamentPK))); + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.Tournament[ tournamentPK=" + + tournamentPK + " ]"; } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java new file mode 100644 index 0000000..5d577c1 --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java @@ -0,0 +1,141 @@ +package com.github.javydreamercsw.database.storage.db; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + +@Entity +@Table(name = "tournament_format") +@XmlRootElement +@NamedQueries( +{ + @NamedQuery(name = "TournamentFormat.findAll", + query = "SELECT t FROM TournamentFormat t"), + @NamedQuery(name = "TournamentFormat.findById", + query = "SELECT t FROM TournamentFormat t WHERE t.id = :id"), + @NamedQuery(name = "TournamentFormat.findByFormatName", + query = "SELECT t FROM TournamentFormat t WHERE t.formatName = :formatName"), + @NamedQuery(name = "TournamentFormat.findByImplementationClass", + query = "SELECT t FROM TournamentFormat t WHERE t.implementationClass = :implementationClass") +}) +public class TournamentFormat implements Serializable +{ + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 45) + @Column(name = "format_name") + private String formatName; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 255) + @Column(name = "implementation_class") + private String implementationClass; + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TournamentFormatGen") + @TableGenerator(name = "TournamentFormatGen", table = "tm_id", + pkColumnName = "table_name", + valueColumnName = "last_id", + pkColumnValue = "tournament_format", + allocationSize = 1, + initialValue = 1) + private Integer id; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "tournamentFormat") + private List tournamentList; + + public TournamentFormat() + { + } + + public TournamentFormat(String formatName, String implementationClass) + { + this.formatName = formatName; + this.implementationClass = implementationClass; + } + + public Integer getId() + { + return id; + } + + public void setId(Integer id) + { + this.id = id; + } + + public String getFormatName() + { + return formatName; + } + + public void setFormatName(String formatName) + { + this.formatName = formatName; + } + + public String getImplementationClass() + { + return implementationClass; + } + + public void setImplementationClass(String implementationClass) + { + this.implementationClass = implementationClass; + } + + @XmlTransient + public List getTournamentList() + { + return tournamentList; + } + + public void setTournamentList(List tournamentList) + { + this.tournamentList = tournamentList; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (id != null ? id.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof TournamentFormat)) + { + return false; + } + TournamentFormat other = (TournamentFormat) object; + return !((this.id == null && other.id != null) + || (this.id != null && !this.id.equals(other.id))); + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.TournamentFormat[ id=" + id + " ]"; + } +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentHasTeam.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentHasTeam.java index b03dc9c..5443661 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentHasTeam.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentHasTeam.java @@ -6,6 +6,7 @@ import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.JoinColumn; +import javax.persistence.JoinColumns; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; @@ -19,7 +20,8 @@ @XmlRootElement @NamedQueries( { - @NamedQuery(name = "TournamentHasTeam.findAll", query = "SELECT t FROM TournamentHasTeam t"), + @NamedQuery(name = "TournamentHasTeam.findAll", + query = "SELECT t FROM TournamentHasTeam t"), @NamedQuery(name = "TournamentHasTeam.findByTournamentId", query = "SELECT t FROM TournamentHasTeam t WHERE t.tournamentHasTeamPK.tournamentId = :tournamentId"), @NamedQuery(name = "TournamentHasTeam.findByTeamId", @@ -36,8 +38,14 @@ public class TournamentHasTeam implements Serializable updatable = false) @ManyToOne(optional = false) private Team team; - @JoinColumn(name = "tournament_id", referencedColumnName = "id", - insertable = false, updatable = false) + @JoinColumns( + { + @JoinColumn(name = "tournament_id", referencedColumnName = "id", + insertable = false, updatable = false), + @JoinColumn(name = "tournament_tournament_format_id", + referencedColumnName = "tournament_format_id", + insertable = false, updatable = false) + }) @ManyToOne(optional = false) private Tournament tournament; diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentPK.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentPK.java new file mode 100644 index 0000000..67df055 --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentPK.java @@ -0,0 +1,93 @@ +package com.github.javydreamercsw.database.storage.db; + +import java.io.Serializable; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.TableGenerator; +import javax.validation.constraints.NotNull; + +@Embeddable +public class TournamentPK implements Serializable +{ + private static final long serialVersionUID = -5852922586504031795L; + @Basic(optional = false) + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TournamentGen") + @TableGenerator(name = "TournamentGen", table = "tm_id", + pkColumnName = "table_name", + valueColumnName = "last_id", + pkColumnValue = "tournament", + allocationSize = 1, + initialValue = 1) + private int id; + @Basic(optional = false) + @NotNull + @Column(name = "tournament_format_id") + private int tournamentFormatId; + + public TournamentPK() + { + + } + + public TournamentPK(int tournamentFormatId) + { + this.tournamentFormatId = tournamentFormatId; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public int getTournamentFormatId() + { + return tournamentFormatId; + } + + public void setTournamentFormatId(int tournamentFormatId) + { + this.tournamentFormatId = tournamentFormatId; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (int) id; + hash += (int) tournamentFormatId; + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof TournamentPK)) + { + return false; + } + TournamentPK other = (TournamentPK) object; + if (this.id != other.id) + { + return false; + } + return this.tournamentFormatId == other.tournamentFormatId; + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.TournamentPK[ id=" + + id + ", tournamentFormatId=" + tournamentFormatId + " ]"; + } +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java index 3980bbd..3cd8e84 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/PlayerJpaController.java @@ -30,25 +30,25 @@ public void create(Player player) { if (player.getTeamList() == null) { - player.setTeamList(new ArrayList()); + player.setTeamList(new ArrayList<>()); } if (player.getRecordList() == null) { - player.setRecordList(new ArrayList()); + player.setRecordList(new ArrayList<>()); } EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); - List attachedTeamList = new ArrayList(); + List attachedTeamList = new ArrayList<>(); for (Team teamListTeamToAttach : player.getTeamList()) { teamListTeamToAttach = em.getReference(teamListTeamToAttach.getClass(), teamListTeamToAttach.getId()); attachedTeamList.add(teamListTeamToAttach); } player.setTeamList(attachedTeamList); - List attachedRecordList = new ArrayList(); + List attachedRecordList = new ArrayList<>(); for (Record recordListRecordToAttach : player.getRecordList()) { recordListRecordToAttach = em.getReference(recordListRecordToAttach.getClass(), recordListRecordToAttach.getRecordPK()); @@ -89,7 +89,7 @@ public void edit(Player player) throws NonexistentEntityException, Exception List teamListNew = player.getTeamList(); List recordListOld = persistentPlayer.getRecordList(); List recordListNew = player.getRecordList(); - List attachedTeamListNew = new ArrayList(); + List attachedTeamListNew = new ArrayList<>(); for (Team teamListNewTeamToAttach : teamListNew) { teamListNewTeamToAttach = em.getReference(teamListNewTeamToAttach.getClass(), teamListNewTeamToAttach.getId()); @@ -97,7 +97,7 @@ public void edit(Player player) throws NonexistentEntityException, Exception } teamListNew = attachedTeamListNew; player.setTeamList(teamListNew); - List attachedRecordListNew = new ArrayList(); + List attachedRecordListNew = new ArrayList<>(); for (Record recordListNewRecordToAttach : recordListNew) { recordListNewRecordToAttach = em.getReference(recordListNewRecordToAttach.getClass(), recordListNewRecordToAttach.getRecordPK()); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RoundJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RoundJpaController.java index c58fbc7..0b3ba9c 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RoundJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/RoundJpaController.java @@ -39,7 +39,7 @@ public void create(Round round) throws PreexistingEntityException, Exception { round.setMatchEntryList(new ArrayList<>()); } - round.getRoundPK().setTournamentId(round.getTournament().getId()); + round.getRoundPK().setTournamentId(round.getTournament().getTournamentPK().getId()); EntityManager em = null; try { @@ -48,7 +48,7 @@ public void create(Round round) throws PreexistingEntityException, Exception Tournament tournament = round.getTournament(); if (tournament != null) { - tournament = em.getReference(tournament.getClass(), tournament.getId()); + tournament = em.getReference(tournament.getClass(), tournament.getTournamentPK()); round.setTournament(tournament); } List attachedMatchEntryList = new ArrayList<>(); @@ -96,7 +96,7 @@ public void create(Round round) throws PreexistingEntityException, Exception public void edit(Round round) throws IllegalOrphanException, NonexistentEntityException, Exception { - round.getRoundPK().setTournamentId(round.getTournament().getId()); + round.getRoundPK().setTournamentId(round.getTournament().getTournamentPK().getId()); EntityManager em = null; try { @@ -125,7 +125,7 @@ public void edit(Round round) throws IllegalOrphanException, NonexistentEntityEx } if (tournamentNew != null) { - tournamentNew = em.getReference(tournamentNew.getClass(), tournamentNew.getId()); + tournamentNew = em.getReference(tournamentNew.getClass(), tournamentNew.getTournamentPK()); round.setTournament(tournamentNew); } List attachedMatchEntryListNew = new ArrayList<>(); @@ -294,5 +294,5 @@ public int getRoundCount() em.close(); } } - + } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentFormatJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentFormatJpaController.java new file mode 100644 index 0000000..8efc1e2 --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentFormatJpaController.java @@ -0,0 +1,257 @@ +package com.github.javydreamercsw.database.storage.db.controller; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityNotFoundException; +import javax.persistence.Query; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentFormat; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.PreexistingEntityException; +import com.github.javydreamercsw.database.storage.db.server.AbstractController; + +public class TournamentFormatJpaController extends AbstractController implements Serializable +{ + private static final long serialVersionUID = 8124092964263662804L; + + public TournamentFormatJpaController(EntityManagerFactory emf) + { + super(emf); + } + + public void create(TournamentFormat tournamentFormat) throws PreexistingEntityException, Exception + { + if (tournamentFormat.getTournamentList() == null) + { + tournamentFormat.setTournamentList(new ArrayList<>()); + } + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + List attachedTournamentList = new ArrayList<>(); + for (Tournament tournamentListTournamentToAttach : tournamentFormat.getTournamentList()) + { + tournamentListTournamentToAttach = em.getReference(tournamentListTournamentToAttach.getClass(), tournamentListTournamentToAttach.getTournamentPK()); + attachedTournamentList.add(tournamentListTournamentToAttach); + } + tournamentFormat.setTournamentList(attachedTournamentList); + em.persist(tournamentFormat); + for (Tournament tournamentListTournament : tournamentFormat.getTournamentList()) + { + TournamentFormat oldTournamentFormatOfTournamentListTournament = tournamentListTournament.getTournamentFormat(); + tournamentListTournament.setTournamentFormat(tournamentFormat); + tournamentListTournament = em.merge(tournamentListTournament); + if (oldTournamentFormatOfTournamentListTournament != null) + { + oldTournamentFormatOfTournamentListTournament.getTournamentList().remove(tournamentListTournament); + oldTournamentFormatOfTournamentListTournament = em.merge(oldTournamentFormatOfTournamentListTournament); + } + } + em.getTransaction().commit(); + } + catch (Exception ex) + { + if (tournamentFormat.getId() != null + && findTournamentFormat(tournamentFormat.getId()) != null) + { + throw new PreexistingEntityException("TournamentFormat " + tournamentFormat + " already exists.", ex); + } + throw ex; + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public void edit(TournamentFormat tournamentFormat) throws IllegalOrphanException, NonexistentEntityException, Exception + { + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + TournamentFormat persistentTournamentFormat = em.find(TournamentFormat.class, tournamentFormat.getId()); + List tournamentListOld = persistentTournamentFormat.getTournamentList(); + List tournamentListNew = tournamentFormat.getTournamentList(); + List illegalOrphanMessages = null; + for (Tournament tournamentListOldTournament : tournamentListOld) + { + if (!tournamentListNew.contains(tournamentListOldTournament)) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("You must retain Tournament " + tournamentListOldTournament + " since its tournamentFormat field is not nullable."); + } + } + if (illegalOrphanMessages != null) + { + throw new IllegalOrphanException(illegalOrphanMessages); + } + List attachedTournamentListNew = new ArrayList<>(); + for (Tournament tournamentListNewTournamentToAttach : tournamentListNew) + { + tournamentListNewTournamentToAttach = em.getReference(tournamentListNewTournamentToAttach.getClass(), tournamentListNewTournamentToAttach.getTournamentPK()); + attachedTournamentListNew.add(tournamentListNewTournamentToAttach); + } + tournamentListNew = attachedTournamentListNew; + tournamentFormat.setTournamentList(tournamentListNew); + tournamentFormat = em.merge(tournamentFormat); + for (Tournament tournamentListNewTournament : tournamentListNew) + { + if (!tournamentListOld.contains(tournamentListNewTournament)) + { + TournamentFormat oldTournamentFormatOfTournamentListNewTournament = tournamentListNewTournament.getTournamentFormat(); + tournamentListNewTournament.setTournamentFormat(tournamentFormat); + tournamentListNewTournament = em.merge(tournamentListNewTournament); + if (oldTournamentFormatOfTournamentListNewTournament != null && !oldTournamentFormatOfTournamentListNewTournament.equals(tournamentFormat)) + { + oldTournamentFormatOfTournamentListNewTournament.getTournamentList().remove(tournamentListNewTournament); + oldTournamentFormatOfTournamentListNewTournament = em.merge(oldTournamentFormatOfTournamentListNewTournament); + } + } + } + em.getTransaction().commit(); + } + catch (Exception ex) + { + String msg = ex.getLocalizedMessage(); + if (msg == null || msg.length() == 0) + { + Integer id = tournamentFormat.getId(); + if (findTournamentFormat(id) == null) + { + throw new NonexistentEntityException("The tournamentFormat with id " + id + " no longer exists."); + } + } + throw ex; + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException + { + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + TournamentFormat tournamentFormat; + try + { + tournamentFormat = em.getReference(TournamentFormat.class, id); + tournamentFormat.getId(); + } + catch (EntityNotFoundException enfe) + { + throw new NonexistentEntityException("The tournamentFormat with id " + id + " no longer exists.", enfe); + } + List illegalOrphanMessages = null; + List tournamentListOrphanCheck = tournamentFormat.getTournamentList(); + for (Tournament tournamentListOrphanCheckTournament : tournamentListOrphanCheck) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("This TournamentFormat (" + tournamentFormat + ") cannot be destroyed since the Tournament " + tournamentListOrphanCheckTournament + " in its tournamentList field has a non-nullable tournamentFormat field."); + } + if (illegalOrphanMessages != null) + { + throw new IllegalOrphanException(illegalOrphanMessages); + } + em.remove(tournamentFormat); + em.getTransaction().commit(); + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public List findTournamentFormatEntities() + { + return findTournamentFormatEntities(true, -1, -1); + } + + public List findTournamentFormatEntities(int maxResults, int firstResult) + { + return findTournamentFormatEntities(false, maxResults, firstResult); + } + + private List findTournamentFormatEntities(boolean all, int maxResults, int firstResult) + { + EntityManager em = getEntityManager(); + try + { + CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); + cq.select(cq.from(TournamentFormat.class)); + Query q = em.createQuery(cq); + if (!all) + { + q.setMaxResults(maxResults); + q.setFirstResult(firstResult); + } + return q.getResultList(); + } + finally + { + em.close(); + } + } + + public TournamentFormat findTournamentFormat(Integer id) + { + EntityManager em = getEntityManager(); + try + { + return em.find(TournamentFormat.class, id); + } + finally + { + em.close(); + } + } + + public int getTournamentFormatCount() + { + EntityManager em = getEntityManager(); + try + { + CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); + Root rt = cq.from(TournamentFormat.class); + cq.select(em.getCriteriaBuilder().count(rt)); + Query q = em.createQuery(cq); + return ((Long) q.getSingleResult()).intValue(); + } + finally + { + em.close(); + } + } + +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java index bcbfdcd..80bc46c 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentHasTeamJpaController.java @@ -39,8 +39,8 @@ public void create(TournamentHasTeam tournamentHasTeam) throws PreexistingEntity { tournamentHasTeam.setRecordList(new ArrayList<>()); } - tournamentHasTeam.getTournamentHasTeamPK().setTournamentId(tournamentHasTeam.getTournament().getId()); tournamentHasTeam.getTournamentHasTeamPK().setTeamId(tournamentHasTeam.getTeam().getId()); + tournamentHasTeam.getTournamentHasTeamPK().setTournamentId(tournamentHasTeam.getTournament().getTournamentPK().getId()); EntityManager em = null; try { @@ -55,7 +55,7 @@ public void create(TournamentHasTeam tournamentHasTeam) throws PreexistingEntity Tournament tournament = tournamentHasTeam.getTournament(); if (tournament != null) { - tournament = em.getReference(tournament.getClass(), tournament.getId()); + tournament = em.getReference(tournament.getClass(), tournament.getTournamentPK()); tournamentHasTeam.setTournament(tournament); } List attachedRecordList = new ArrayList<>(); @@ -102,8 +102,8 @@ public void create(TournamentHasTeam tournamentHasTeam) throws PreexistingEntity public void edit(TournamentHasTeam tournamentHasTeam) throws NonexistentEntityException, Exception { - tournamentHasTeam.getTournamentHasTeamPK().setTournamentId(tournamentHasTeam.getTournament().getId()); tournamentHasTeam.getTournamentHasTeamPK().setTeamId(tournamentHasTeam.getTeam().getId()); + tournamentHasTeam.getTournamentHasTeamPK().setTournamentId(tournamentHasTeam.getTournament().getTournamentPK().getId()); EntityManager em = null; try { @@ -123,7 +123,7 @@ public void edit(TournamentHasTeam tournamentHasTeam) throws NonexistentEntityEx } if (tournamentNew != null) { - tournamentNew = em.getReference(tournamentNew.getClass(), tournamentNew.getId()); + tournamentNew = em.getReference(tournamentNew.getClass(), tournamentNew.getTournamentPK()); tournamentHasTeam.setTournament(tournamentNew); } List attachedRecordListNew = new ArrayList<>(); @@ -302,5 +302,5 @@ public int getTournamentHasTeamCount() em.close(); } } - + } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java index a12e9aa..4ae25bd 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java @@ -13,42 +13,48 @@ import com.github.javydreamercsw.database.storage.db.Round; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.github.javydreamercsw.database.storage.db.TournamentHasTeam; +import com.github.javydreamercsw.database.storage.db.TournamentPK; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.PreexistingEntityException; import com.github.javydreamercsw.database.storage.db.server.AbstractController; public class TournamentJpaController extends AbstractController implements Serializable { - private static final long serialVersionUID = -3241408395907726172L; - + private static final long serialVersionUID = 2285164831364920828L; public TournamentJpaController(EntityManagerFactory emf) { super(emf); } - public void create(Tournament tournament) + public void create(Tournament tournament) throws PreexistingEntityException, Exception { - if (tournament.getRoundList() == null) + if (tournament.getTournamentPK() == null) { - tournament.setRoundList(new ArrayList<>()); + tournament.setTournamentPK(new TournamentPK()); } if (tournament.getTournamentHasTeamList() == null) { tournament.setTournamentHasTeamList(new ArrayList<>()); } + if (tournament.getRoundList() == null) + { + tournament.setRoundList(new ArrayList<>()); + } + tournament.getTournamentPK().setTournamentFormatId(tournament.getTournamentFormat().getId()); EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); - List attachedRoundList = new ArrayList<>(); - for (Round roundListRoundToAttach : tournament.getRoundList()) + TournamentFormat tournamentFormat = tournament.getTournamentFormat(); + if (tournamentFormat != null) { - roundListRoundToAttach = em.getReference(roundListRoundToAttach.getClass(), roundListRoundToAttach.getRoundPK()); - attachedRoundList.add(roundListRoundToAttach); + tournamentFormat = em.getReference(tournamentFormat.getClass(), tournamentFormat.getId()); + tournament.setTournamentFormat(tournamentFormat); } - tournament.setRoundList(attachedRoundList); List attachedTournamentHasTeamList = new ArrayList<>(); for (TournamentHasTeam tournamentHasTeamListTournamentHasTeamToAttach : tournament.getTournamentHasTeamList()) { @@ -56,17 +62,18 @@ public void create(Tournament tournament) attachedTournamentHasTeamList.add(tournamentHasTeamListTournamentHasTeamToAttach); } tournament.setTournamentHasTeamList(attachedTournamentHasTeamList); + List attachedRoundList = new ArrayList<>(); + for (Round roundListRoundToAttach : tournament.getRoundList()) + { + roundListRoundToAttach = em.getReference(roundListRoundToAttach.getClass(), roundListRoundToAttach.getRoundPK()); + attachedRoundList.add(roundListRoundToAttach); + } + tournament.setRoundList(attachedRoundList); em.persist(tournament); - for (Round roundListRound : tournament.getRoundList()) + if (tournamentFormat != null) { - Tournament oldTournamentOfRoundListRound = roundListRound.getTournament(); - roundListRound.setTournament(tournament); - roundListRound = em.merge(roundListRound); - if (oldTournamentOfRoundListRound != null) - { - oldTournamentOfRoundListRound.getRoundList().remove(roundListRound); - oldTournamentOfRoundListRound = em.merge(oldTournamentOfRoundListRound); - } + tournamentFormat.getTournamentList().add(tournament); + tournamentFormat = em.merge(tournamentFormat); } for (TournamentHasTeam tournamentHasTeamListTournamentHasTeam : tournament.getTournamentHasTeamList()) { @@ -79,8 +86,27 @@ public void create(Tournament tournament) oldTournamentOfTournamentHasTeamListTournamentHasTeam = em.merge(oldTournamentOfTournamentHasTeamListTournamentHasTeam); } } + for (Round roundListRound : tournament.getRoundList()) + { + Tournament oldTournamentOfRoundListRound = roundListRound.getTournament(); + roundListRound.setTournament(tournament); + roundListRound = em.merge(roundListRound); + if (oldTournamentOfRoundListRound != null) + { + oldTournamentOfRoundListRound.getRoundList().remove(roundListRound); + oldTournamentOfRoundListRound = em.merge(oldTournamentOfRoundListRound); + } + } em.getTransaction().commit(); } + catch (Exception ex) + { + if (findTournament(tournament.getTournamentPK()) != null) + { + throw new PreexistingEntityException("Tournament " + tournament + " already exists.", ex); + } + throw ex; + } finally { if (em != null) @@ -92,51 +118,51 @@ public void create(Tournament tournament) public void edit(Tournament tournament) throws IllegalOrphanException, NonexistentEntityException, Exception { + tournament.getTournamentPK().setTournamentFormatId(tournament.getTournamentFormat().getId()); EntityManager em = null; try { em = getEntityManager(); em.getTransaction().begin(); - Tournament persistentTournament = em.find(Tournament.class, tournament.getId()); - List roundListOld = persistentTournament.getRoundList(); - List roundListNew = tournament.getRoundList(); + Tournament persistentTournament = em.find(Tournament.class, tournament.getTournamentPK()); + TournamentFormat tournamentFormatOld = persistentTournament.getTournamentFormat(); + TournamentFormat tournamentFormatNew = tournament.getTournamentFormat(); List tournamentHasTeamListOld = persistentTournament.getTournamentHasTeamList(); List tournamentHasTeamListNew = tournament.getTournamentHasTeamList(); + List roundListOld = persistentTournament.getRoundList(); + List roundListNew = tournament.getRoundList(); List illegalOrphanMessages = null; - for (Round roundListOldRound : roundListOld) + for (TournamentHasTeam tournamentHasTeamListOldTournamentHasTeam : tournamentHasTeamListOld) { - if (!roundListNew.contains(roundListOldRound)) + if (!tournamentHasTeamListNew.contains(tournamentHasTeamListOldTournamentHasTeam)) { if (illegalOrphanMessages == null) { illegalOrphanMessages = new ArrayList<>(); } - illegalOrphanMessages.add("You must retain Round " + roundListOldRound + " since its tournament field is not nullable."); + illegalOrphanMessages.add("You must retain TournamentHasTeam " + tournamentHasTeamListOldTournamentHasTeam + " since its tournament field is not nullable."); } } - for (TournamentHasTeam tournamentHasTeamListOldTournamentHasTeam : tournamentHasTeamListOld) + for (Round roundListOldRound : roundListOld) { - if (!tournamentHasTeamListNew.contains(tournamentHasTeamListOldTournamentHasTeam)) + if (!roundListNew.contains(roundListOldRound)) { if (illegalOrphanMessages == null) { illegalOrphanMessages = new ArrayList<>(); } - illegalOrphanMessages.add("You must retain TournamentHasTeam " + tournamentHasTeamListOldTournamentHasTeam + " since its tournament field is not nullable."); + illegalOrphanMessages.add("You must retain Round " + roundListOldRound + " since its tournament field is not nullable."); } } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); } - List attachedRoundListNew = new ArrayList<>(); - for (Round roundListNewRoundToAttach : roundListNew) + if (tournamentFormatNew != null) { - roundListNewRoundToAttach = em.getReference(roundListNewRoundToAttach.getClass(), roundListNewRoundToAttach.getRoundPK()); - attachedRoundListNew.add(roundListNewRoundToAttach); + tournamentFormatNew = em.getReference(tournamentFormatNew.getClass(), tournamentFormatNew.getId()); + tournament.setTournamentFormat(tournamentFormatNew); } - roundListNew = attachedRoundListNew; - tournament.setRoundList(roundListNew); List attachedTournamentHasTeamListNew = new ArrayList<>(); for (TournamentHasTeam tournamentHasTeamListNewTournamentHasTeamToAttach : tournamentHasTeamListNew) { @@ -145,20 +171,24 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste } tournamentHasTeamListNew = attachedTournamentHasTeamListNew; tournament.setTournamentHasTeamList(tournamentHasTeamListNew); + List attachedRoundListNew = new ArrayList<>(); + for (Round roundListNewRoundToAttach : roundListNew) + { + roundListNewRoundToAttach = em.getReference(roundListNewRoundToAttach.getClass(), roundListNewRoundToAttach.getRoundPK()); + attachedRoundListNew.add(roundListNewRoundToAttach); + } + roundListNew = attachedRoundListNew; + tournament.setRoundList(roundListNew); tournament = em.merge(tournament); - for (Round roundListNewRound : roundListNew) + if (tournamentFormatOld != null && !tournamentFormatOld.equals(tournamentFormatNew)) { - if (!roundListOld.contains(roundListNewRound)) - { - Tournament oldTournamentOfRoundListNewRound = roundListNewRound.getTournament(); - roundListNewRound.setTournament(tournament); - roundListNewRound = em.merge(roundListNewRound); - if (oldTournamentOfRoundListNewRound != null && !oldTournamentOfRoundListNewRound.equals(tournament)) - { - oldTournamentOfRoundListNewRound.getRoundList().remove(roundListNewRound); - oldTournamentOfRoundListNewRound = em.merge(oldTournamentOfRoundListNewRound); - } - } + tournamentFormatOld.getTournamentList().remove(tournament); + tournamentFormatOld = em.merge(tournamentFormatOld); + } + if (tournamentFormatNew != null && !tournamentFormatNew.equals(tournamentFormatOld)) + { + tournamentFormatNew.getTournamentList().add(tournament); + tournamentFormatNew = em.merge(tournamentFormatNew); } for (TournamentHasTeam tournamentHasTeamListNewTournamentHasTeam : tournamentHasTeamListNew) { @@ -174,6 +204,20 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste } } } + for (Round roundListNewRound : roundListNew) + { + if (!roundListOld.contains(roundListNewRound)) + { + Tournament oldTournamentOfRoundListNewRound = roundListNewRound.getTournament(); + roundListNewRound.setTournament(tournament); + roundListNewRound = em.merge(roundListNewRound); + if (oldTournamentOfRoundListNewRound != null && !oldTournamentOfRoundListNewRound.equals(tournament)) + { + oldTournamentOfRoundListNewRound.getRoundList().remove(roundListNewRound); + oldTournamentOfRoundListNewRound = em.merge(oldTournamentOfRoundListNewRound); + } + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -181,7 +225,7 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste String msg = ex.getLocalizedMessage(); if (msg == null || msg.length() == 0) { - Integer id = tournament.getId(); + TournamentPK id = tournament.getTournamentPK(); if (findTournament(id) == null) { throw new NonexistentEntityException("The tournament with id " + id + " no longer exists."); @@ -198,7 +242,7 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste } } - public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException + public void destroy(TournamentPK id) throws IllegalOrphanException, NonexistentEntityException { EntityManager em = null; try @@ -209,35 +253,41 @@ public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntity try { tournament = em.getReference(Tournament.class, id); - tournament.getId(); + tournament.getTournamentPK(); } catch (EntityNotFoundException enfe) { throw new NonexistentEntityException("The tournament with id " + id + " no longer exists.", enfe); } List illegalOrphanMessages = null; - List roundListOrphanCheck = tournament.getRoundList(); - for (Round roundListOrphanCheckRound : roundListOrphanCheck) + List tournamentHasTeamListOrphanCheck = tournament.getTournamentHasTeamList(); + for (TournamentHasTeam tournamentHasTeamListOrphanCheckTournamentHasTeam : tournamentHasTeamListOrphanCheck) { if (illegalOrphanMessages == null) { illegalOrphanMessages = new ArrayList<>(); } - illegalOrphanMessages.add("This Tournament (" + tournament + ") cannot be destroyed since the Round " + roundListOrphanCheckRound + " in its roundList field has a non-nullable tournament field."); + illegalOrphanMessages.add("This Tournament (" + tournament + ") cannot be destroyed since the TournamentHasTeam " + tournamentHasTeamListOrphanCheckTournamentHasTeam + " in its tournamentHasTeamList field has a non-nullable tournament field."); } - List tournamentHasTeamListOrphanCheck = tournament.getTournamentHasTeamList(); - for (TournamentHasTeam tournamentHasTeamListOrphanCheckTournamentHasTeam : tournamentHasTeamListOrphanCheck) + List roundListOrphanCheck = tournament.getRoundList(); + for (Round roundListOrphanCheckRound : roundListOrphanCheck) { if (illegalOrphanMessages == null) { illegalOrphanMessages = new ArrayList<>(); } - illegalOrphanMessages.add("This Tournament (" + tournament + ") cannot be destroyed since the TournamentHasTeam " + tournamentHasTeamListOrphanCheckTournamentHasTeam + " in its tournamentHasTeamList field has a non-nullable tournament field."); + illegalOrphanMessages.add("This Tournament (" + tournament + ") cannot be destroyed since the Round " + roundListOrphanCheckRound + " in its roundList field has a non-nullable tournament field."); } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); } + TournamentFormat tournamentFormat = tournament.getTournamentFormat(); + if (tournamentFormat != null) + { + tournamentFormat.getTournamentList().remove(tournament); + tournamentFormat = em.merge(tournamentFormat); + } em.remove(tournament); em.getTransaction().commit(); } @@ -281,7 +331,7 @@ private List findTournamentEntities(boolean all, int maxResults, int } } - public Tournament findTournament(Integer id) + public Tournament findTournament(TournamentPK id) { EntityManager em = getEntityManager(); try @@ -310,5 +360,5 @@ public int getTournamentCount() em.close(); } } - + } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index a837e3a..61112c8 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -5,6 +5,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -33,8 +34,10 @@ import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.github.javydreamercsw.tournament.manager.api.GameFormat; import com.github.javydreamercsw.tournament.manager.api.IGame; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; import com.github.javydreamercsw.tournament.manager.api.storage.StorageException; import com.googlecode.flyway.core.Flyway; import com.googlecode.flyway.core.api.MigrationInfo; @@ -455,6 +458,8 @@ public static void nativeUpdateQuery(String query) @SuppressWarnings("empty-statement") public static void loadDemoData() throws Exception { + Random r = new Random(); + // Add players for (int i = 0; i < 10; i++) { @@ -469,12 +474,16 @@ public static void loadDemoData() throws Exception } // Add a tournaments + List formats = new ArrayList<>(); + formats.addAll(Lookup.getDefault().lookupAll(TournamentInterface.class)); for (int i = 0; i < 10; i++) { Tournament t = new Tournament("Tournament " + (i + 1)); t.setWinPoints(3); t.setLossPoints(0); t.setDrawPoints(1); + t.setTournamentFormat(TournamentService.getInstance() + .findFormat(formats.get(r.nextInt(formats.size())).getName())); TournamentService.getInstance().saveTournament(t); } @@ -510,7 +519,7 @@ public static void loadDemoData() throws Exception } List formatList = FormatService.getInstance() .findFormatByGame(gameAPI.getName()); - Random r = new Random(); + // Add matches for (int i = 0; i < 10; i++) { @@ -554,6 +563,21 @@ public static void loadDemoData() throws Exception */ public static void load() { + Lookup.getDefault().lookupAll(TournamentInterface.class).forEach(format -> + { + // Register the tournament formats + if (TournamentService.getInstance().findFormat(format.getName()) == null) + { + try { + TournamentFormat tf = new TournamentFormat(format.getName(), + format.getClass().getCanonicalName()); + TournamentService.getInstance().addFormat(tf); + } + catch (Exception ex) { + Exceptions.printStackTrace(ex); + } + } + }); Lookup.getDefault().lookupAll(IGame.class).forEach(gameAPI -> { // Add game to DB if not there diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java index 576dc2f..d4b44c3 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java @@ -6,8 +6,11 @@ import com.github.javydreamercsw.database.storage.db.Round; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.github.javydreamercsw.database.storage.db.TournamentHasTeam; +import com.github.javydreamercsw.database.storage.db.TournamentPK; import com.github.javydreamercsw.database.storage.db.controller.RoundJpaController; +import com.github.javydreamercsw.database.storage.db.controller.TournamentFormatJpaController; import com.github.javydreamercsw.database.storage.db.controller.TournamentHasTeamJpaController; import com.github.javydreamercsw.database.storage.db.controller.TournamentJpaController; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; @@ -21,6 +24,8 @@ public class TournamentService extends Service = new TournamentHasTeamJpaController(DataBaseManager.getEntityManagerFactory()); private RoundJpaController rc = new RoundJpaController(DataBaseManager.getEntityManagerFactory()); + private TournamentFormatJpaController tfc + = new TournamentFormatJpaController(DataBaseManager.getEntityManagerFactory()); private TournamentService() { @@ -73,12 +78,12 @@ public List findTournaments(String value) return result; } - public void saveTournament(Tournament t) throws NonexistentEntityException, + public void saveTournament(Tournament t) throws NonexistentEntityException, IllegalOrphanException, Exception { - if (t.getId() != null && tc.findTournament(t.getId()) != null) + if (t.getTournamentPK() != null && tc.findTournament(t.getTournamentPK()) != null) { - tc.edit(t); + tc.edit(t); } else { @@ -98,10 +103,10 @@ public void deleteTournament(Tournament t) throws IllegalOrphanException, { deleteTeamFromTournament(tht); } - tc.destroy(t.getId()); + tc.destroy(t.getTournamentPK()); } - public Tournament findTournament(Integer id) + public Tournament findTournament(TournamentPK id) { return tc.findTournament(id); } @@ -125,7 +130,7 @@ public void addTeams(Tournament t, List teams) throws Exception * @param teams Teams to add * @throws Exception if there's an error adding teams. */ - public void addTeams(Tournament t, Team... teams) throws Exception + public void addTeams(Tournament t, Team... teams) throws Exception { for (Team team : teams) { @@ -141,7 +146,7 @@ public void addTeams(Tournament t, Team... teams) throws Exception * @throws IllegalOrphanException if an orphan is left * @throws Exception if there's an error adding team. */ - public void addTeam(Tournament t, Team team) throws IllegalOrphanException, + public void addTeam(Tournament t, Team team) throws IllegalOrphanException, Exception { TournamentHasTeam tht = new TournamentHasTeam(); @@ -205,4 +210,26 @@ public void deleteRound(Round round) throws IllegalOrphanException, { rc.destroy(round.getRoundPK()); } + + public TournamentFormat findFormat(String name) + { + for (TournamentFormat tf : tfc.findTournamentFormatEntities()) + { + if (tf.getFormatName().equals(name)) + { + return tf; + } + } + return null; + } + + public void addFormat(TournamentFormat tf) throws Exception + { + tfc.create(tf); + } + + public List getFormats() + { + return tfc.findTournamentFormatEntities(); + } } diff --git a/Database-Storage/src/main/resources/META-INF/persistence.xml b/Database-Storage/src/main/resources/META-INF/persistence.xml index 46f05f3..b6d5218 100644 --- a/Database-Storage/src/main/resources/META-INF/persistence.xml +++ b/Database-Storage/src/main/resources/META-INF/persistence.xml @@ -13,6 +13,7 @@ com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team com.github.javydreamercsw.database.storage.db.Tournament + com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam @@ -39,6 +40,7 @@ com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team com.github.javydreamercsw.database.storage.db.Tournament + com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam @@ -66,6 +68,7 @@ com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team com.github.javydreamercsw.database.storage.db.Tournament + com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index 60c5173..a9ecc14 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -22,6 +22,7 @@ import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.tournament.manager.api.IGame; import com.github.javydreamercsw.tournament.manager.api.TournamentException; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; /** * @@ -41,6 +42,9 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, game = GameService.getInstance().findGameByName(Lookup.getDefault() .lookup(IGame.class).getName()).get(); Tournament t = new Tournament("Test 1"); + t.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); TournamentService.getInstance().saveTournament(t); TournamentService.getInstance().addRound(t); @@ -63,6 +67,9 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, public void testMatchService() throws TournamentException, Exception { Tournament t = new Tournament("Test 1"); + t.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); TournamentService.getInstance().saveTournament(t); TournamentService.getInstance().addRound(t); diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java new file mode 100644 index 0000000..fe23acb --- /dev/null +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java @@ -0,0 +1,53 @@ +package com.github.javydreamercsw.database.storage.db.server; + + +import java.util.List; + +import org.openide.util.lookup.ServiceProvider; + +import com.github.javydreamercsw.tournament.manager.AbstractTournament; +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; + +@ServiceProvider(service = TournamentInterface.class) +public class TestTournamentFormat extends AbstractTournament + implements TournamentInterface +{ + public TestTournamentFormat() + { + super(3, 0, 1, true); + } + + public TestTournamentFormat(int winPoints, int lossPoints, int drawPoints, + boolean pairAlikeRecords) + { + super(winPoints, lossPoints, drawPoints, pairAlikeRecords); + } + + public TestTournamentFormat(int winPoints, int lossPoints, int drawPoints) + { + super(winPoints, lossPoints, drawPoints); + } + + @Override + public String getName() + { + return "Dummy Tournament"; + } + + @Override + public int getMinimumAmountOfRounds() + { + return 2; + } + + @Override + public TournamentInterface createTournament(List teams, + int winPoints, int lossPoints, int drawPoints) + { + TestTournamentFormat dummy = new TestTournamentFormat(winPoints, lossPoints, + drawPoints, true); + dummy.teams.addAll(teams); + return dummy; + } +} diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java index e9949c3..4dbffa4 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java @@ -9,6 +9,7 @@ import java.util.List; import org.openide.util.Exceptions; +import org.openide.util.Lookup; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -16,8 +17,10 @@ import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentPK; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; /** * @@ -35,6 +38,9 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException { super.setup(); t = new Tournament("Test"); + t.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); TournamentService.getInstance().saveTournament(t); } catch (Exception ex) @@ -69,8 +75,8 @@ public void testAddTeam() throws Exception @Test public void testFindTournament() { - assertNotNull(TournamentService.getInstance().findTournament(t.getId())); - assertNull(TournamentService.getInstance().findTournament(2_000)); + assertNotNull(TournamentService.getInstance().findTournament(t.getTournamentPK())); + assertNull(TournamentService.getInstance().findTournament(new TournamentPK(2_000))); } @Test @@ -83,10 +89,13 @@ public void testFindTournaments() } @Test - public void testSaveAndDelete() throws IllegalOrphanException, + public void testSaveAndDelete() throws IllegalOrphanException, NonexistentEntityException, Exception { Tournament t2 = new Tournament("Test 2"); + t2.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) .size(), 0); @@ -105,8 +114,11 @@ public void testSaveAndDelete() throws IllegalOrphanException, public void testAddTeams() throws Exception { Tournament tournament = new Tournament("Add Team"); + tournament.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); TournamentService.getInstance().saveTournament(tournament); - + Player player3 = new Player("Player 3"); PlayerService.getInstance().savePlayer(player3); @@ -127,14 +139,14 @@ public void testAddTeams() throws Exception team3.getPlayerList().add(player3); team3.getPlayerList().add(player5); TeamService.getInstance().saveTeam(team3); - - List teams= new ArrayList<>(); + + List teams = new ArrayList<>(); teams.add(team3); teams.add(team2); TournamentService.getInstance().addTeams(tournament, teams); - assertEquals(TournamentService.getInstance().findTournament(tournament.getId()) - .getTournamentHasTeamList().size(), 2); + assertEquals(TournamentService.getInstance().findTournament(tournament + .getTournamentPK()).getTournamentHasTeamList().size(), 2); } } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java index bc71273..305d68e 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java @@ -131,16 +131,7 @@ private void addFormat() cb.setRequired(true); cb.setPreventInvalidInput(true); cb.setAllowCustomValue(false); - cb.addValueChangeListener(new ValueChangeListener() - { - private static final long serialVersionUID = 5377566605252849942L; - - @Override - public void valueChanged(ValueChangeEvent e) - { - validate(); - } - }); + cb.addValueChangeListener(listener -> validate()); getBinder().forField(cb).bind(MatchEntry::getFormat, MatchEntry::setFormat); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java index f1a4102..6068df5 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java @@ -15,15 +15,20 @@ */ package com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist; +import java.util.ArrayList; +import java.util.List; import java.util.function.BiConsumer; import java.util.function.Consumer; import com.github.javydreamercsw.database.storage.db.Format; import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.github.javydreamercsw.database.storage.db.server.TournamentService; import com.github.javydreamercsw.tournament.manager.ui.common.AbstractEditorDialog; +import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.data.converter.StringToIntegerConverter; +import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.data.validator.StringLengthValidator; /** @@ -36,6 +41,7 @@ public class TournamentEditorDialog extends AbstractEditorDialog private final TextField winPoints = new TextField("Points per win"); private final TextField lossPoints = new TextField("Points per loss"); private final TextField drawPoints = new TextField("Points per draw"); + private final ComboBox format = new ComboBox<>("Format"); public TournamentEditorDialog(BiConsumer itemSaver, Consumer itemDeleter) @@ -46,6 +52,7 @@ public TournamentEditorDialog(BiConsumer itemSaver, addNameWinPoints(); addNameLossPoints(); addNameDrawPoints(); + addTournamentFormat(); } @Override @@ -63,8 +70,15 @@ private void addNameField() .withValidator(new StringLengthValidator( "Tournament name must contain at least 3 printable characters", 3, null)) - .withValidator(name -> TournamentService.getInstance() - .findTournaments(name).isEmpty(), + .withValidator(name -> + { + List results + = TournamentService.getInstance().findTournaments(name); + return results.isEmpty() + || (results.size() == 1 + && getCurrentItem().getTournamentPK() + .equals(results.get(0).getTournamentPK())); + }, "Tournament name must be unique") .bind(Tournament::getName, Tournament::setName); } @@ -73,6 +87,8 @@ private void addNameWinPoints() { getFormLayout().add(winPoints); + winPoints.addValueChangeListener(listener -> validate()); + getBinder().forField(winPoints) .withConverter( new StringToIntegerConverter("Must enter a number")) @@ -81,7 +97,9 @@ private void addNameWinPoints() private void addNameLossPoints() { - getFormLayout().add(lossPoints); + getFormLayout().add(lossPoints); + + lossPoints.addValueChangeListener(listener -> validate()); getBinder().forField(lossPoints) .withConverter( @@ -93,9 +111,57 @@ private void addNameDrawPoints() { getFormLayout().add(drawPoints); + drawPoints.addValueChangeListener(listener -> validate()); + getBinder().forField(drawPoints) .withConverter( new StringToIntegerConverter("Must enter a number")) .bind(Tournament::getDrawPoints, Tournament::setDrawPoints); } + + private void addTournamentFormat() + { + getFormLayout().add(format); + + List formats = new ArrayList<>(); + formats.addAll(TournamentService.getInstance().getFormats()); + + format.setDataProvider(new ListDataProvider(formats)); + format.setItemLabelGenerator(new TournamentFormatLabelGenerator()); + format.setRequired(true); + format.setPreventInvalidInput(true); + format.setAllowCustomValue(false); + format.addValueChangeListener(listener -> validate()); + + format.setEnabled(formats.size() > 1); + if (formats.size() == 1) + { + // Select the only option + format.setValue(formats.get(0)); + } + + getBinder().forField(format) + .bind(Tournament::getTournamentFormat, + Tournament::setTournamentFormat); + } + + @Override + protected boolean isValid() + { + if (getCurrentItem().getTournamentFormat() == null) + { + // No format + return false; + } + if (getCurrentItem().getWinPoints() <= getCurrentItem().getLossPoints() + || getCurrentItem().getWinPoints() <= getCurrentItem().getDrawPoints()) + { + // Win points are less than loss and/or draw. + return false; + } + + // All are zero + return getCurrentItem().getDrawPoints() + getCurrentItem().getLossPoints() + + getCurrentItem().getWinPoints() > 0; + } } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java new file mode 100644 index 0000000..3f2573d --- /dev/null +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java @@ -0,0 +1,15 @@ +package com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist; + +import com.github.javydreamercsw.database.storage.db.TournamentFormat; +import com.vaadin.flow.component.ItemLabelGenerator; + +class TournamentFormatLabelGenerator implements ItemLabelGenerator +{ + private static final long serialVersionUID = -738603579674658479L; + + @Override + public String apply(TournamentFormat f) + { + return f.getFormatName(); + } +} diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java index 629fccb..fc69484 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java @@ -101,6 +101,11 @@ private String getTeamCount(Tournament t) { return Integer.toString(t.getTournamentHasTeamList().size()); } + + private String getFormat(Tournament t) + { + return t.getTournamentFormat().getFormatName(); + } private void addContent() { @@ -114,6 +119,8 @@ private void addContent() .setWidth("6em"); grid.addColumn(this::getTeamCount).setHeader("Teams") .setWidth("6em"); + grid.addColumn(this::getFormat).setHeader("Format") + .setWidth("6em"); grid.addColumn(new ComponentRenderer<>(this::createEditButton)) .setFlexGrow(0); grid.setSelectionMode(SelectionMode.NONE); @@ -169,7 +176,7 @@ private void saveTournament(Tournament t, private void deleteTournament(Tournament t) { - if (TournamentService.getInstance().findTournament(t.getId()) != null) + if (TournamentService.getInstance().findTournament(t.getTournamentPK()) != null) { try { From b3a9f979aaed05ffb48fb400ddcd482619fc9718 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 07:55:27 -0600 Subject: [PATCH 10/25] Separate into single and double elimination formats. --- .../tournament/DoubleElimination.java | 41 +++++++++++++++++++ .../elimination/tournament/Elimination.java | 19 +-------- .../tournament/SingleElimination.java | 41 +++++++++++++++++++ .../tournament/EliminationTest.java | 19 ++++++++- 4 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java create mode 100644 Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java new file mode 100644 index 0000000..e492b6e --- /dev/null +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java @@ -0,0 +1,41 @@ +package com.github.javydreamercsw.tournament.manager.elimination.tournament; + +import java.util.List; + +import org.openide.util.lookup.ServiceProvider; + +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; + +@ServiceProvider(service = TournamentInterface.class) +public class DoubleElimination extends Elimination +{ + public DoubleElimination() + { + super(2, false); + } + + public DoubleElimination(int winPoints, int lossPoints, int drawPoints, + boolean pairAlikeRecords) + { + super(2, winPoints, lossPoints, drawPoints, pairAlikeRecords); + } + + + + @Override + public String getName() + { + return "Double Elimination"; + } + + @Override + public TournamentInterface createTournament(List teams, + int winPoints, int lossPoints, int drawPoints) + { + DoubleElimination de = new DoubleElimination(winPoints, lossPoints, + drawPoints, true); + de.teams.addAll(teams); + return de; + } +} diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java index 40ea37f..d327e74 100644 --- a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java @@ -10,7 +10,6 @@ import java.util.logging.Logger; import org.apache.commons.lang3.ArrayUtils; -import org.openide.util.lookup.ServiceProvider; import com.github.javydreamercsw.tournament.manager.AbstractTournament; import com.github.javydreamercsw.tournament.manager.api.Encounter; @@ -23,8 +22,7 @@ * * @author Javier A. Ortiz Bultron */ -@ServiceProvider(service = TournamentInterface.class) -public class Elimination extends AbstractTournament +public abstract class Elimination extends AbstractTournament implements TournamentInterface { @@ -70,12 +68,6 @@ public Elimination(int eliminations, int winPoints, int lossPoints, this.eliminations = eliminations; } - @Override - public String getName() - { - return "Single Elimination"; - } - @Override public boolean isTeamActive(TeamInterface t) { @@ -257,13 +249,4 @@ public int getMinimumAmountOfRounds() */ return log(teams.size(), 2); } - - @Override - public TournamentInterface createTournament(List teams, - int winPoints, int lossPoints, int drawPoints) - { - Elimination swiss = new Elimination(1, winPoints, lossPoints, drawPoints, true); - swiss.teams.addAll(teams); - return swiss; - } } diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java new file mode 100644 index 0000000..2ceecb5 --- /dev/null +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java @@ -0,0 +1,41 @@ +package com.github.javydreamercsw.tournament.manager.elimination.tournament; + +import java.util.List; + +import org.openide.util.lookup.ServiceProvider; + +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; + +@ServiceProvider(service = TournamentInterface.class) +public class SingleElimination extends Elimination +{ + public SingleElimination() + { + super(1, false); + } + + public SingleElimination(int winPoints, int lossPoints, int drawPoints, + boolean pairAlikeRecords) + { + super(1, winPoints, lossPoints, drawPoints, pairAlikeRecords); + } + + + + @Override + public String getName() + { + return "Single Elimination"; + } + + @Override + public TournamentInterface createTournament(List teams, + int winPoints, int lossPoints, int drawPoints) + { + SingleElimination se = new SingleElimination(winPoints, lossPoints, + drawPoints, true); + se.teams.addAll(teams); + return se; + } +} diff --git a/Elimination-Tournament/src/test/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/EliminationTest.java b/Elimination-Tournament/src/test/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/EliminationTest.java index bf9b1c4..019349e 100644 --- a/Elimination-Tournament/src/test/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/EliminationTest.java +++ b/Elimination-Tournament/src/test/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/EliminationTest.java @@ -1,11 +1,12 @@ package com.github.javydreamercsw.tournament.manager.elimination.tournament; - +import java.util.List; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import com.github.javydreamercsw.tournament.manager.AbstractTournamentTester; +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; /** @@ -23,7 +24,21 @@ public TournamentInterface generateRandomTournament() { int eliminations = new Random().nextInt(2) + 1; LOG.log(Level.INFO, "Eliminations: {0}", eliminations); - return new Elimination(eliminations, new Random().nextBoolean()); + return new Elimination(eliminations, 3, 0, 1, new Random().nextBoolean()) + { + @Override + public String getName() + { + return "Elimination: " + eliminations; + } + + @Override + public TournamentInterface createTournament(List teams, + int winPoints, int lossPoints, int drawPoints) + { + return null; + } + }; } @Override From f8cbf1e93b8614102a77a0f22d76ed7754e3f2ca Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 08:25:20 -0600 Subject: [PATCH 11/25] Import fail instead of the bogus local method created by mistake. --- .../tournament/manager/AbstractTournamentTester.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java index f74c853..bf68acb 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java @@ -3,6 +3,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import java.text.MessageFormat; import java.util.ArrayList; @@ -354,9 +355,4 @@ public void testSimulateTournament() * @return */ public abstract TournamentInterface generateRandomTournament(); - - private void fail() - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } } From 766b57f7230d3504cb7f492759139a5af211e3fa Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 09:13:17 -0600 Subject: [PATCH 12/25] Change some messages and log levels. --- .../manager/elimination/tournament/Elimination.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java index d327e74..b16c2e5 100644 --- a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java @@ -116,7 +116,7 @@ public Map getPairings() { try { - LOG.log(Level.FINE, "Removing player: {0}", t.toString()); + LOG.log(Level.FINE, "Player: {0} is eliminated!", t.toString()); removeTeam(t); } catch (TournamentException ex) @@ -186,7 +186,7 @@ public Map getPairings() pending = players.get(lucky); //Exclude the lucky one from the rest of processing exclude = ArrayUtils.add(exclude, lucky); - LOG.log(Level.INFO, "Pairing {0} with lower level", pending); + LOG.log(Level.FINE, "Pairing {0} with lower level", pending); } //We have an even number, pair them together while (players.size() - exclude.length >= 2) From b65964d1165ea0fcd7803af71767baedd2955c0e Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 10:01:39 -0600 Subject: [PATCH 13/25] Randomize ranked/unranked matches. --- .../database/storage/db/server/DataBaseManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index 61112c8..050a376 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -536,12 +536,14 @@ public static void loadDemoData() throws Exception //Add a result boolean win = r.nextBoolean(); + boolean ranked = r.nextBoolean(); MatchService.getInstance().setResult(match.getMatchHasTeamList().get(0), MatchService.getInstance().getResultType(win ? "result.win" : "result.loss").get()); MatchService.getInstance().setResult(match.getMatchHasTeamList().get(1), MatchService.getInstance().getResultType(win ? "result.loss" : "result.win").get()); + MatchService.getInstance().setRanked(match, ranked); //Lock the results so records are updated. match.getMatchHasTeamList().forEach(mht -> From 767d66f1af03e7c2e798ade77b3beb60f91beffa Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 10:02:11 -0600 Subject: [PATCH 14/25] New method to set a match ranked/unranked. --- .../storage/db/server/MatchService.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index fabd228..acc6a1e 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -21,6 +21,7 @@ import com.github.javydreamercsw.database.storage.db.controller.MatchResultTypeJpaController; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.api.TournamentException; public class MatchService extends Service { @@ -181,7 +182,7 @@ public boolean addTeam(MatchEntry match, Team team) throws Exception boolean found = false; for (Record r : player.getRecordList()) { - if (Objects.equals(r.getGame().getId(), + if (Objects.equals(r.getGame().getId(), match.getFormat().getGame().getId())) { found = true; @@ -342,7 +343,7 @@ public void lockMatchResult(MatchResult mr) throws Exception /** * Update a match result. - * + * * @param mr Match result to update. * @throws Exception If result doesn't exist. */ @@ -357,4 +358,29 @@ public void updateResult(MatchResult mr) throws Exception throw new Exception("Trying to update non existing result!"); } } + + /** + * Set match results ranked or unranked. + * + * @param match Match to update. + * @param ranked true for ranked, false for unranked. + * @throws TournamentException if results are already locked. + * @throws Exception If there's an error updating the result. + */ + public void setRanked(MatchEntry match, boolean ranked) + throws TournamentException, Exception + { + for (MatchHasTeam mht : match.getMatchHasTeamList()) + { + if (!mht.getMatchResult().getLocked()) + { + mht.getMatchResult().setRanked(ranked); + MatchService.getInstance().updateResult(mht.getMatchResult()); + } + else + { + throw new TournamentException("Rsults already locked!"); + } + } + } } From 949cdb9f9553be369f54d984aa215144f5c7b3da Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 10:02:30 -0600 Subject: [PATCH 15/25] Use service method instead. --- .../manager/ui/views/matchlist/MatchEditorDialog.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java index 305d68e..43334ef 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java @@ -193,8 +193,8 @@ private void addRanked() { if (mht.getMatchResult() != null) { - mht.getMatchResult().setRanked(ranked.getValue()); - MatchService.getInstance().updateResult(mht.getMatchResult()); + MatchService.getInstance().setRanked(getCurrentItem(), + ranked.getValue()); } } catch (Exception ex) From 8472015600032ba0c539470b06ab97507b1bd8ac Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Tue, 4 Dec 2018 10:02:52 -0600 Subject: [PATCH 16/25] If not using demo, load normally. --- .../manager/ui/views/welcome/Welcome.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java index bb4c638..b3d495e 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java @@ -31,20 +31,20 @@ public class Welcome extends TMView { private static final long serialVersionUID = 1252548231807630022L; private static boolean demo = false; - + static { try { InitialContext context = new InitialContext(); - + String JNDIDB = (String) context .lookup("java:comp/env/tm/JNDIDB"); - + DataBaseManager.setPersistenceUnitName(JNDIDB); demo = (Boolean) context .lookup("java:comp/env/tm/demo"); - + DataBaseManager.load(); } catch (NamingException ex) @@ -97,6 +97,13 @@ public void valueChanged(ValueChangeEvent e) Exceptions.printStackTrace(ex); } } + else + { + DataBaseManager.load(); + Notification.show( + "Loading data done!", + 3000, Position.MIDDLE); + } } }); cb.setEnabled(games.size() > 1); From 31274cce4c1644b305ffba06b4e4ea6f43e54cb6 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Thu, 6 Dec 2018 12:32:23 -0600 Subject: [PATCH 17/25] #6: Add round pairing functionality. --- Database-Storage/DB.mwb | Bin 27910 -> 28933 bytes Database-Storage/DB.mwb.bak | Bin 27296 -> 28886 bytes .../database/storage/db/Format.java | 62 ++- .../database/storage/db/Round.java | 31 +- .../database/storage/db/Tournament.java | 49 +- .../db/controller/FormatJpaController.java | 67 +++ .../controller/TournamentJpaController.java | 35 ++ .../storage/db/server/DataBaseManager.java | 1 + .../storage/db/server/MatchService.java | 8 +- .../storage/db/server/TournamentService.java | 352 +++++++++++- .../storage/db/server/MatchServiceTest.java | 22 +- .../db/server/TestTournamentFormat.java | 6 +- .../db/server/TournamentServiceTest.java | 214 ++++++- .../tournament/DoubleElimination.java | 16 +- .../elimination/tournament/Elimination.java | 41 +- .../tournament/SingleElimination.java | 6 +- .../swiss/tournament/Swiss.java | 7 +- .../manager/AbstractTournament.java | 142 +++-- .../tournament/manager/Team.java | 57 +- .../tournament/manager/api/Encounter.java | 31 +- .../manager/api/EncounterResult.java | 2 +- .../manager/api/NoShowListener.java | 13 - .../manager/api/RoundTimeListener.java | 13 - .../tournament/manager/api/TeamInterface.java | 23 +- .../manager/api/TournamentInterface.java | 521 +++++++++--------- .../manager/api/TournamentListener.java | 31 ++ .../manager/AbstractTournamentTest.java | 23 +- .../manager/AbstractTournamentTester.java | 52 +- .../tournament/manager/EncounterTest.java | 4 +- .../tournament/manager/TeamTest.java | 4 +- .../TrueSkillRankingProviderNGTest.java | 6 +- .../views/tournamentlist/TournamentList.java | 46 +- .../manager/ui/views/welcome/Welcome.java | 65 ++- 33 files changed, 1396 insertions(+), 554 deletions(-) delete mode 100644 TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/NoShowListener.java delete mode 100644 TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/RoundTimeListener.java create mode 100644 TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentListener.java diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index 0da7646b07e998cd41f39323c3d2601c688af369..4c366ebb958c73c9556cb7e66e31b55ae73d753a 100644 GIT binary patch literal 28933 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 HA>#i5d=3*y literal 27910 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 S34?T;JX}9n{L|hH<^KWU3_Ak= diff --git a/Database-Storage/DB.mwb.bak b/Database-Storage/DB.mwb.bak index b23c06d1608b88f0071e5d0380ae45707bca5449..bceba4fafbe475f5ce374bd1189d1f46a6e0b623 100644 GIT binary patch literal 28886 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 N8DwklPq{+4{{v8|P?P`w literal 27296 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 matchEntryList; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "format") + private List tournamentList; public Format() { @@ -83,6 +85,25 @@ public void setFormatPK(FormatPK formatPK) this.formatPK = formatPK; } + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } public Game getGame() { @@ -105,6 +126,17 @@ public void setMatchEntryList(List matchEntryList) this.matchEntryList = matchEntryList; } + @XmlTransient + public List getTournamentList() + { + return tournamentList; + } + + public void setTournamentList(List tournamentList) + { + this.tournamentList = tournamentList; + } + @Override public int hashCode() { @@ -129,27 +161,7 @@ public boolean equals(Object object) @Override public String toString() { - return "com.github.javydreamercsw.database.storage.db.Format[ formatPK=" + - formatPK + " ]"; - } - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDescription() - { - return description; - } - - public void setDescription(String description) - { - this.description = description; + return "com.github.javydreamercsw.database.storage.db.Format[ formatPK=" + + formatPK + " ]"; } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Round.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Round.java index 4bd3458..8cc0092 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Round.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Round.java @@ -4,7 +4,9 @@ import java.util.ArrayList; import java.util.List; +import javax.persistence.Basic; import javax.persistence.CascadeType; +import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.JoinColumn; @@ -14,6 +16,7 @@ import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; +import javax.validation.constraints.NotNull; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; @@ -35,17 +38,21 @@ public class Round implements Serializable @EmbeddedId protected RoundPK roundPK; @JoinColumns( - { - @JoinColumn(name = "tournament_id", referencedColumnName = "id", - insertable = false, updatable = false), - @JoinColumn(name = "tournament_tournament_format_id", - referencedColumnName = "tournament_format_id", - insertable = false, updatable = false) - }) + { + @JoinColumn(name = "tournament_id", referencedColumnName = "id", + insertable = false, updatable = false), + @JoinColumn(name = "tournament_tournament_format_id", + referencedColumnName = "tournament_format_id", + insertable = false, updatable = false) + }) @ManyToOne(optional = false) private Tournament tournament; @OneToMany(cascade = CascadeType.ALL, mappedBy = "round") private List matchEntryList; + @Basic(optional = false) + @NotNull + @Column(name = "roundNumber") + private int roundNumber; public Round() { @@ -120,4 +127,14 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.Round[ roundPK=" + roundPK + " ]"; } + + public int getRoundNumber() + { + return roundNumber; + } + + public void setRoundNumber(int roundNumber) + { + this.roundNumber = roundNumber; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java index 3522fdd..4e43df9 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java @@ -1,6 +1,7 @@ package com.github.javydreamercsw.database.storage.db; import java.io.Serializable; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -10,6 +11,7 @@ import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.JoinColumn; +import javax.persistence.JoinColumns; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; @@ -37,7 +39,11 @@ @NamedQuery(name = "Tournament.findByDrawPoints", query = "SELECT t FROM Tournament t WHERE t.drawPoints = :drawPoints"), @NamedQuery(name = "Tournament.findByLossPoints", - query = "SELECT t FROM Tournament t WHERE t.lossPoints = :lossPoints") + query = "SELECT t FROM Tournament t WHERE t.lossPoints = :lossPoints"), + @NamedQuery(name = "Tournament.findByStartDate", + query = "SELECT t FROM Tournament t WHERE t.startDate = :startDate"), + @NamedQuery(name = "Tournament.findByEndDate", + query = "SELECT t FROM Tournament t WHERE t.endDate = :endDate") }) public class Tournament implements Serializable { @@ -61,6 +67,17 @@ public class Tournament implements Serializable @NotNull @Column(name = "lossPoints") private int lossPoints; + @Column(name = "startDate") + private LocalDate startDate; + @Column(name = "endDate") + private LocalDate endDate; + @JoinColumns( + { + @JoinColumn(name = "format_id", referencedColumnName = "id"), + @JoinColumn(name = "format_game_id", referencedColumnName = "game_id") + }) + @ManyToOne(optional = false) + private Format format; @JoinColumn(name = "tournament_format_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) @@ -145,6 +162,36 @@ public void setLossPoints(int lossPoints) this.lossPoints = lossPoints; } + public LocalDate getStartDate() + { + return startDate; + } + + public void setStartDate(LocalDate startDate) + { + this.startDate = startDate; + } + + public LocalDate getEndDate() + { + return endDate; + } + + public void setEndDate(LocalDate endDate) + { + this.endDate = endDate; + } + + public Format getFormat() + { + return format; + } + + public void setFormat(Format format) + { + this.format = format; + } + public TournamentFormat getTournamentFormat() { return tournamentFormat; diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java index 966e3c6..0d918e7 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java @@ -15,6 +15,7 @@ import com.github.javydreamercsw.database.storage.db.FormatPK; import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.PreexistingEntityException; @@ -38,6 +39,10 @@ public void create(Format format) throws PreexistingEntityException, Exception { format.setMatchEntryList(new ArrayList<>()); } + if (format.getTournamentList() == null) + { + format.setTournamentList(new ArrayList<>()); + } format.getFormatPK().setGameId(format.getGame().getId()); EntityManager em = null; try @@ -57,6 +62,13 @@ public void create(Format format) throws PreexistingEntityException, Exception attachedMatchEntryList.add(matchEntryListMatchEntryToAttach); } format.setMatchEntryList(attachedMatchEntryList); + List attachedTournamentList = new ArrayList<>(); + for (Tournament tournamentListTournamentToAttach : format.getTournamentList()) + { + tournamentListTournamentToAttach = em.getReference(tournamentListTournamentToAttach.getClass(), tournamentListTournamentToAttach.getTournamentPK()); + attachedTournamentList.add(tournamentListTournamentToAttach); + } + format.setTournamentList(attachedTournamentList); em.persist(format); if (game != null) { @@ -74,6 +86,17 @@ public void create(Format format) throws PreexistingEntityException, Exception oldFormatOfMatchEntryListMatchEntry = em.merge(oldFormatOfMatchEntryListMatchEntry); } } + for (Tournament tournamentListTournament : format.getTournamentList()) + { + Format oldFormatOfTournamentListTournament = tournamentListTournament.getFormat(); + tournamentListTournament.setFormat(format); + tournamentListTournament = em.merge(tournamentListTournament); + if (oldFormatOfTournamentListTournament != null) + { + oldFormatOfTournamentListTournament.getTournamentList().remove(tournamentListTournament); + oldFormatOfTournamentListTournament = em.merge(oldFormatOfTournamentListTournament); + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -106,6 +129,8 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity Game gameNew = format.getGame(); List matchEntryListOld = persistentFormat.getMatchEntryList(); List matchEntryListNew = format.getMatchEntryList(); + List tournamentListOld = persistentFormat.getTournamentList(); + List tournamentListNew = format.getTournamentList(); List illegalOrphanMessages = null; for (MatchEntry matchEntryListOldMatchEntry : matchEntryListOld) { @@ -118,6 +143,17 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity illegalOrphanMessages.add("You must retain MatchEntry " + matchEntryListOldMatchEntry + " since its format field is not nullable."); } } + for (Tournament tournamentListOldTournament : tournamentListOld) + { + if (!tournamentListNew.contains(tournamentListOldTournament)) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("You must retain Tournament " + tournamentListOldTournament + " since its format field is not nullable."); + } + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); @@ -135,6 +171,14 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity } matchEntryListNew = attachedMatchEntryListNew; format.setMatchEntryList(matchEntryListNew); + List attachedTournamentListNew = new ArrayList<>(); + for (Tournament tournamentListNewTournamentToAttach : tournamentListNew) + { + tournamentListNewTournamentToAttach = em.getReference(tournamentListNewTournamentToAttach.getClass(), tournamentListNewTournamentToAttach.getTournamentPK()); + attachedTournamentListNew.add(tournamentListNewTournamentToAttach); + } + tournamentListNew = attachedTournamentListNew; + format.setTournamentList(tournamentListNew); format = em.merge(format); if (gameOld != null && !gameOld.equals(gameNew)) { @@ -160,6 +204,20 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity } } } + for (Tournament tournamentListNewTournament : tournamentListNew) + { + if (!tournamentListOld.contains(tournamentListNewTournament)) + { + Format oldFormatOfTournamentListNewTournament = tournamentListNewTournament.getFormat(); + tournamentListNewTournament.setFormat(format); + tournamentListNewTournament = em.merge(tournamentListNewTournament); + if (oldFormatOfTournamentListNewTournament != null && !oldFormatOfTournamentListNewTournament.equals(format)) + { + oldFormatOfTournamentListNewTournament.getTournamentList().remove(tournamentListNewTournament); + oldFormatOfTournamentListNewTournament = em.merge(oldFormatOfTournamentListNewTournament); + } + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -211,6 +269,15 @@ public void destroy(FormatPK id) throws IllegalOrphanException, NonexistentEntit } illegalOrphanMessages.add("This Format (" + format + ") cannot be destroyed since the MatchEntry " + matchEntryListOrphanCheckMatchEntry + " in its matchEntryList field has a non-nullable format field."); } + List tournamentListOrphanCheck = format.getTournamentList(); + for (Tournament tournamentListOrphanCheckTournament : tournamentListOrphanCheck) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("This Format (" + format + ") cannot be destroyed since the Tournament " + tournamentListOrphanCheckTournament + " in its tournamentList field has a non-nullable format field."); + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java index 4ae25bd..959a65a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TournamentJpaController.java @@ -11,6 +11,7 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; +import com.github.javydreamercsw.database.storage.db.Format; import com.github.javydreamercsw.database.storage.db.Round; import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.TournamentFormat; @@ -49,6 +50,12 @@ public void create(Tournament tournament) throws PreexistingEntityException, Exc { em = getEntityManager(); em.getTransaction().begin(); + Format format = tournament.getFormat(); + if (format != null) + { + format = em.getReference(format.getClass(), format.getFormatPK()); + tournament.setFormat(format); + } TournamentFormat tournamentFormat = tournament.getTournamentFormat(); if (tournamentFormat != null) { @@ -70,6 +77,11 @@ public void create(Tournament tournament) throws PreexistingEntityException, Exc } tournament.setRoundList(attachedRoundList); em.persist(tournament); + if (format != null) + { + format.getTournamentList().add(tournament); + format = em.merge(format); + } if (tournamentFormat != null) { tournamentFormat.getTournamentList().add(tournament); @@ -125,6 +137,8 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste em = getEntityManager(); em.getTransaction().begin(); Tournament persistentTournament = em.find(Tournament.class, tournament.getTournamentPK()); + Format formatOld = persistentTournament.getFormat(); + Format formatNew = tournament.getFormat(); TournamentFormat tournamentFormatOld = persistentTournament.getTournamentFormat(); TournamentFormat tournamentFormatNew = tournament.getTournamentFormat(); List tournamentHasTeamListOld = persistentTournament.getTournamentHasTeamList(); @@ -158,6 +172,11 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste { throw new IllegalOrphanException(illegalOrphanMessages); } + if (formatNew != null) + { + formatNew = em.getReference(formatNew.getClass(), formatNew.getFormatPK()); + tournament.setFormat(formatNew); + } if (tournamentFormatNew != null) { tournamentFormatNew = em.getReference(tournamentFormatNew.getClass(), tournamentFormatNew.getId()); @@ -180,6 +199,16 @@ public void edit(Tournament tournament) throws IllegalOrphanException, Nonexiste roundListNew = attachedRoundListNew; tournament.setRoundList(roundListNew); tournament = em.merge(tournament); + if (formatOld != null && !formatOld.equals(formatNew)) + { + formatOld.getTournamentList().remove(tournament); + formatOld = em.merge(formatOld); + } + if (formatNew != null && !formatNew.equals(formatOld)) + { + formatNew.getTournamentList().add(tournament); + formatNew = em.merge(formatNew); + } if (tournamentFormatOld != null && !tournamentFormatOld.equals(tournamentFormatNew)) { tournamentFormatOld.getTournamentList().remove(tournament); @@ -282,6 +311,12 @@ public void destroy(TournamentPK id) throws IllegalOrphanException, NonexistentE { throw new IllegalOrphanException(illegalOrphanMessages); } + Format format = tournament.getFormat(); + if (format != null) + { + format.getTournamentList().remove(tournament); + format = em.merge(format); + } TournamentFormat tournamentFormat = tournament.getTournamentFormat(); if (tournamentFormat != null) { diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index 050a376..ab1faf3 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -482,6 +482,7 @@ public static void loadDemoData() throws Exception t.setWinPoints(3); t.setLossPoints(0); t.setDrawPoints(1); + t.setFormat(FormatService.getInstance().getAll().get(0)); t.setTournamentFormat(TournamentService.getInstance() .findFormat(formats.get(r.nextInt(formats.size())).getName())); TournamentService.getInstance().saveTournament(t); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index acc6a1e..9da593a 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -314,6 +314,10 @@ public void lockMatchResult(MatchResult mr) throws Exception switch (mr.getMatchResultType().getType()) { case "result.loss": + //Fall thru + case "result.forfeit": + //Fall thru + case "result.no_show": record.setLoses(record.getLoses() + 1); break; case "result.draw": @@ -321,10 +325,6 @@ public void lockMatchResult(MatchResult mr) throws Exception break; //Various reasons leading to a win. case "result.win": - //Fall thru - case "result.forfeit": - //Fall thru - case "result.no_show": record.setWins(record.getWins() + 1); break; } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java index d4b44c3..f1cb9c3 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java @@ -1,9 +1,20 @@ package com.github.javydreamercsw.database.storage.db.server; +import java.time.LocalDate; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; + +import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.MatchHasTeam; +import com.github.javydreamercsw.database.storage.db.MatchResultType; +import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Round; +import com.github.javydreamercsw.database.storage.db.RoundPK; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.TournamentFormat; @@ -15,6 +26,14 @@ import com.github.javydreamercsw.database.storage.db.controller.TournamentJpaController; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.UIPlayer; +import com.github.javydreamercsw.tournament.manager.api.Encounter; +import com.github.javydreamercsw.tournament.manager.api.EncounterResult; +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentException; +import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentListener; +import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; public class TournamentService extends Service { @@ -26,6 +45,7 @@ public class TournamentService extends Service = new RoundJpaController(DataBaseManager.getEntityManagerFactory()); private TournamentFormatJpaController tfc = new TournamentFormatJpaController(DataBaseManager.getEntityManagerFactory()); + private Map tournamentMap = new HashMap<>(); private TournamentService() { @@ -179,6 +199,7 @@ public void addRound(Tournament t, boolean save) throws Exception { Round round = new Round(); round.setTournament(t); + round.setRoundNumber(t.getRoundList().size() + 1); rc.create(round); t.getRoundList().add(round); if (save) @@ -205,12 +226,29 @@ public List getAll() return tc.findTournamentEntities(); } + /** + * Delete round. + * + * @param round + * @throws IllegalOrphanException + * @throws NonexistentEntityException + */ public void deleteRound(Round round) throws IllegalOrphanException, NonexistentEntityException { + for (MatchEntry me:round.getMatchEntryList()) + { + MatchService.getInstance().deleteMatch(me); + } rc.destroy(round.getRoundPK()); } + /** + * Find a tournament format. + * + * @param name format name + * @return Format or null if not found. + */ public TournamentFormat findFormat(String name) { for (TournamentFormat tf : tfc.findTournamentFormatEntities()) @@ -223,13 +261,325 @@ public TournamentFormat findFormat(String name) return null; } + /** + * Add a tournament format + * + * @param tf Format to add + * @throws Exception if something goes wrong creating it. + */ public void addFormat(TournamentFormat tf) throws Exception { tfc.create(tf); } - + public List getFormats() { return tfc.findTournamentFormatEntities(); } + + /** + * Start the tournament.This will set up the first round. + * + * @param tournament Tournament to start. + * @param listeners Tournament listeners + * @throws TournamentException If something goes wrong. + */ + public void startTournament(Tournament tournament, + TournamentListener... listeners) throws TournamentException + { + try + { + // Check it has not been started already. + if (hasStarted(tournament)) + { + throw new TournamentException("Tournament has already been started!"); + } + // Check it's not over already. + if (isOver(tournament)) + { + throw new TournamentException("Tournament is already over!"); + } + + // First get the Tournament Format + Class format + = (Class) Class.forName(tournament + .getTournamentFormat().getImplementationClass()); + + //Convert the DB teams to the JSkill implementation + List teams = new ArrayList<>(); + tournament.getTournamentHasTeamList().forEach(tht -> + { + List players = new ArrayList<>(); + tht.getTeam().getPlayerList().forEach(player -> + { + players.add(new UIPlayer(player.getName(), player.getId())); + }); + teams.add(new com.github.javydreamercsw.tournament.manager.Team( + tht.getTeam().getId(), + tht.getTeam().getName(), players)); + }); + TournamentInterface tf + = Lookup.getDefault().lookup(format) + .createTournament(teams, + tournament.getWinPoints(), + tournament.getLossPoints(), + tournament.getDrawPoints()); + tournamentMap.put(tournament.getTournamentPK(), tf); + + // Add listeners + for (TournamentListener listner : listeners) + { + addTournamentListener(tournament, listner); + } + + // Create first round. + startNextRound(tournament); + } + catch (ClassNotFoundException | TournamentException ex) + { + Exceptions.printStackTrace(ex); + throw new TournamentException("Unable to create tournament!", ex); + } + } + + /** + * Start next round. + * + * @param tournament tournament to start the next round of. + * @throws TournamentException if tournament has not been started or is + * already over. + */ + public void startNextRound(Tournament tournament) throws TournamentException + { + if (isOver(tournament)) + { + throw new TournamentException("Tournament is already over!"); + } + + try + { + if (tournament.getRoundList().isEmpty()) + { + // Mark as started. + tournament.setStartDate(LocalDate.now()); + saveTournament(tournament); + } + + // Get the tournament implementation to build the next round. + TournamentInterface ti = tournamentMap.get(tournament.getTournamentPK()); + + ti.nextRound(); + Map pairings = ti.getPairings(); + if (pairings != null && !pairings.isEmpty()) + { + try + { + // Create a round + TournamentService.getInstance().addRound(tournament); + + Round currentRound + = tournament.getRoundList().get(tournament.getRoundList().size() - 1); + // Persist the round in the database. + for (Encounter encounter : pairings.values()) + { + MatchEntry me = new MatchEntry(); + me.setRound(currentRound); + me.setFormat(tournament.getFormat()); + MatchService.getInstance().saveMatch(me); + for (TeamInterface team : encounter.getEncounterSummary().keySet()) + { + MatchService.getInstance().addTeam(me, + TeamService.getInstance().findTeam(team.getTeamId())); + } + currentRound.getMatchEntryList().add(me); + } + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + throw new TournamentException("Error creating round!", ex); + } + ti.getListeners().forEach(listener -> listener + .roundStart(tournament.getRoundList().size())); + } + else + { + // Tournament is over! + // Mark as ended. + tournament.setEndDate(LocalDate.now()); + saveTournament(tournament); + } + } + catch (IllegalOrphanException ex) + { + Exceptions.printStackTrace(ex); + } + catch (Exception ex) + { + Exceptions.printStackTrace(ex); + } + } + + /** + * Checks if tournament already has started. + * + * @param tournament Tournament to check + * @return true if started, false otherwise. + */ + public boolean hasStarted(Tournament tournament) + { + return findTournament(tournament.getTournamentPK()).getStartDate() != null; + } + + /** + * Checks if tournament already finished. + * + * @param tournament Tournament to check + * @return true if is over, false otherwise. + */ + public boolean isOver(Tournament tournament) + { + return findTournament(tournament.getTournamentPK()).getEndDate() != null; + } + + /** + * get a round by id. + * + * @param roundPK ID. + * @return Round with the given ID or null if not found. + */ + public Round getRound(RoundPK roundPK) + { + return rc.findRound(roundPK); + } + + /** + * Add a round time listener. + * + * @param tournament Tournament to add listener to. + * @param listener Listener to add. + * @throws TournamentException if tournament is not found. + */ + public void addTournamentListener(Tournament tournament, + TournamentListener listener) throws TournamentException + { + if (tournamentMap.containsKey(tournament.getTournamentPK())) + { + tournamentMap.get(tournament.getTournamentPK()) + .addTournamentListener(listener); + } + else + { + throw new TournamentException("Tournament not found!"); + } + } + + /** + * Remove a round time listener. + * + * @param tournament Tournament to remove listener from. + * @param listener Listener to remove. + * @throws TournamentException if tournament is not found. + */ + public void removeRoundListener(Tournament tournament, + TournamentListener listener) throws TournamentException + { + if (tournamentMap.containsKey(tournament.getTournamentPK())) + { + tournamentMap.get(tournament.getTournamentPK()) + .removeTournamentListener(listener); + } + else + { + throw new TournamentException("Tournament not found!"); + } + } + + public void setResult(Tournament tournament, MatchHasTeam mht, + MatchResultType rt) throws Exception + { + // Update the running tournament results. + final TournamentInterface ti + = tournamentMap.get(tournament.getTournamentPK()); + + synchronized (ti) + { + // Update database + MatchService.getInstance().setResult(mht, rt); + for (Player player : mht.getTeam().getPlayerList()) + { + // Update runtime + for (Encounter e : ti.getRound(tournament.getRoundList().size()).values()) + { + for (TeamInterface team : e.getEncounterSummary().keySet()) + { + if (team.hasMember(player.getId())) + { + EncounterResult result; + switch (rt.getType()) + { + case "result.noshow": + result = EncounterResult.NO_SHOW; + break; + case "result.forfeit": + result = EncounterResult.FORFEIT; + break; + case "result.loss": + result = EncounterResult.LOSS; + break; + case "result.draw": + result = EncounterResult.DRAW; + break; + default: + result = EncounterResult.WIN; + } + e.updateResult(team, result); + } + } + } + } + int roundNumber = mht.getMatchEntry().getRound().getRoundNumber(); + if (isRoundOver(tournament, roundNumber)) + { + ti.processRound(roundNumber); + ti.getListeners().forEach(listener -> listener.roundOver(roundNumber)); + } + } + } + + /** + * Check if the round is over or not. + * + * @param t Tournament to check + * @param round Round to check + * @return true if over, false otherwise. + */ + public boolean isRoundOver(Tournament t, int round) + { + return getRound(t, round).getMatchEntryList().stream().noneMatch((me) + -> (!me.getMatchHasTeamList().stream().noneMatch((mht) + -> (mht.getMatchResult() == null)))); + } + + /** + * Get round for a tournament. + * + * @param t Tournament to get round from. + * @param round Round number to get. + * @return The round or null if not found. + */ + public Round getRound(Tournament t, int round) + { + List rounds = findTournament(t.getTournamentPK()).getRoundList(); + if (rounds.size() >= round) + { + return rounds.get(round - 1); + } + return null; + } + + public void checkStatus(Tournament t) + { + + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index a9ecc14..14821d9 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -43,8 +43,9 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, .lookup(IGame.class).getName()).get(); Tournament t = new Tournament("Test 1"); t.setTournamentFormat(TournamentService.getInstance() - .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) - .getName())); + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); + t.setFormat(FormatService.getInstance().getAll().get(0)); TournamentService.getInstance().saveTournament(t); TournamentService.getInstance().addRound(t); @@ -68,8 +69,9 @@ public void testMatchService() throws TournamentException, Exception { Tournament t = new Tournament("Test 1"); t.setTournamentFormat(TournamentService.getInstance() - .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) - .getName())); + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); + t.setFormat(FormatService.getInstance().getAll().get(0)); TournamentService.getInstance().saveTournament(t); TournamentService.getInstance().addRound(t); @@ -132,7 +134,12 @@ public void testMatchService() throws TournamentException, Exception { switch (result.getMatchResultType().getType()) { + //Various reasons leading to a loss. case "result.loss": + //Fall thru + case "result.forfeit": + //Fall thru + case "result.no_show": assertEquals(p.getRecordList().get(0).getWins(), 0); assertEquals(p.getRecordList().get(0).getLoses(), 1); assertEquals(p.getRecordList().get(0).getDraws(), 0); @@ -142,12 +149,7 @@ public void testMatchService() throws TournamentException, Exception assertEquals(p.getRecordList().get(0).getLoses(), 0); assertEquals(p.getRecordList().get(0).getDraws(), 1); break; - //Various reasons leading to a win. case "result.win": - //Fall thru - case "result.forfeit": - //Fall thru - case "result.no_show": assertEquals(p.getRecordList().get(0).getWins(), 1); assertEquals(p.getRecordList().get(0).getLoses(), 0); assertEquals(p.getRecordList().get(0).getDraws(), 0); @@ -168,7 +170,7 @@ public void testMatchService() throws TournamentException, Exception MatchService.getInstance().saveMatch(me); - for(MatchHasTeam mht:me.getMatchHasTeamList()) + for (MatchHasTeam mht : me.getMatchHasTeamList()) { MatchResult mr = mht.getMatchResult(); assertNotNull(mr); diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java index fe23acb..05139b8 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java @@ -8,6 +8,7 @@ import com.github.javydreamercsw.tournament.manager.AbstractTournament; import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; @ServiceProvider(service = TournamentInterface.class) public class TestTournamentFormat extends AbstractTournament @@ -43,11 +44,12 @@ public int getMinimumAmountOfRounds() @Override public TournamentInterface createTournament(List teams, - int winPoints, int lossPoints, int drawPoints) + int winPoints, int lossPoints, int drawPoints) + throws TournamentSignupException { TestTournamentFormat dummy = new TestTournamentFormat(winPoints, lossPoints, drawPoints, true); - dummy.teams.addAll(teams); + dummy.addTeams(teams); return dummy; } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java index 4dbffa4..b3de3cd 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java @@ -1,26 +1,29 @@ package com.github.javydreamercsw.database.storage.db.server; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.fail; +import static org.testng.Assert.*; import java.util.ArrayList; import java.util.List; +import java.util.Random; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.github.javydreamercsw.database.storage.db.AbstractServerTest; +import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.MatchHasTeam; import com.github.javydreamercsw.database.storage.db.Player; +import com.github.javydreamercsw.database.storage.db.Round; import com.github.javydreamercsw.database.storage.db.Team; import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.TournamentPK; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentListener; /** * @@ -41,6 +44,7 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException t.setTournamentFormat(TournamentService.getInstance() .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) .getName())); + t.setFormat(FormatService.getInstance().getAll().get(0)); TournamentService.getInstance().saveTournament(t); } catch (Exception ex) @@ -94,11 +98,11 @@ public void testSaveAndDelete() throws IllegalOrphanException, { Tournament t2 = new Tournament("Test 2"); t2.setTournamentFormat(TournamentService.getInstance() - .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) - .getName())); + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) .size(), 0); - + t2.setFormat(FormatService.getInstance().getAll().get(0)); TournamentService.getInstance().saveTournament(t2); assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) @@ -115,8 +119,9 @@ public void testAddTeams() throws Exception { Tournament tournament = new Tournament("Add Team"); tournament.setTournamentFormat(TournamentService.getInstance() - .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) - .getName())); + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); + tournament.setFormat(FormatService.getInstance().getAll().get(0)); TournamentService.getInstance().saveTournament(tournament); Player player3 = new Player("Player 3"); @@ -149,4 +154,195 @@ public void testAddTeams() throws Exception assertEquals(TournamentService.getInstance().findTournament(tournament .getTournamentPK()).getTournamentHasTeamList().size(), 2); } + + @DataProvider + public Object[][] getScenarios() + { + return new Object[][] + { + { + 4, 2, 1 // Two teams of 2 people. Should be done in one round. + }, + { + 2, 1, 1 // Two teams of 1 people. Should be done in one round. + }, + { + 8, 1, 3 // Eight teams of 1 people. Should be done in 3 rounds. + }, + { + 16, 2, 3 // Eight teams of 1 people. Should be done in 3 rounds. + } + }; + } + + /** + * This tests the whole workflow of the tournament. + * + * @param amountOfPlayers Players to test with. + * @param playersPerTeam Amount of players in a team. + * @param expectedRounds Expected amount of rounds. + * @throws IllegalOrphanException + */ + @Test(dataProvider = "getScenarios") + public void testTournament(final int amountOfPlayers, + final int playersPerTeam, final int expectedRounds) + throws IllegalOrphanException, Exception + { + Tournament tournament = new Tournament("Workflow"); + tournament.setTournamentFormat(TournamentService.getInstance() + .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) + .getName())); + tournament.setFormat(FormatService.getInstance().getAll().get(0)); + TournamentService.getInstance().saveTournament(tournament); + + int i = TournamentService.getInstance().getAll().size() + 1; + + Player last = null; + for (int x = 1; x <= amountOfPlayers; x++) + { + Player player = new Player("Player " + i); + PlayerService.getInstance().savePlayer(player); + + if (x % playersPerTeam == 0 && x >= 1) + { + // Create a team with previous player + Team team = new Team("Test Team " + (x / playersPerTeam)); + if (last != null) + { + team.getPlayerList().add(last); + } + team.getPlayerList().add(player); + TeamService.getInstance().saveTeam(team); + TournamentService.getInstance().addTeam(tournament, team); + last = null; + } + else + { + // Save for next team + last = player; + } + i++; + } + + assertEquals(tournament.getTournamentHasTeamList().size(), + amountOfPlayers / playersPerTeam); + + assertEquals(tournament.getRoundList().size(), 0); + + assertFalse(TournamentService.getInstance().hasStarted(tournament)); + + int currentRound = 0; + List roundStarted = new ArrayList<>(); + List roundOver = new ArrayList<>(); + // Start the tournament + TournamentService.getInstance().startTournament(tournament, + new TournamentListener() + { + @Override + public void roundStart(int round) + { + roundStarted.add(round); + } + + @Override + public void roundTimeOver() + { + // Do nothing + } + + @Override + public void roundOver(int round) + { + roundOver.add(round); + } + + @Override + public void noshow() + { + // Do nothing + } + }); + + currentRound++; + + assertTrue(TournamentService.getInstance().hasStarted(tournament)); + + assertEquals(currentRound, (int) roundStarted.get(roundStarted.size() - 1)); + + assertEquals(tournament.getRoundList().size(), currentRound); + + assertEquals(tournament.getRoundList().get(0).getMatchEntryList().size(), + amountOfPlayers / (playersPerTeam * 2)); + + Round retrievedRound = TournamentService.getInstance() + .getRound(tournament.getRoundList().get(0).getRoundPK()); + + assertNotNull(retrievedRound); + + assertEquals(retrievedRound.getMatchEntryList().size(), + amountOfPlayers / (playersPerTeam * 2)); + + assertFalse(TournamentService.getInstance().isRoundOver(tournament, + currentRound)); + + Random random = new Random(); + + //Now simulate matches and monitor the persistence of the round as it progresses. + while (!TournamentService.getInstance().isOver(tournament)) + { + // Simulate matches in the current round + for (MatchEntry me : retrievedRound.getMatchEntryList()) + { + int teams = me.getMatchHasTeamList().size(); + int winner = random.nextInt(teams); + int count = 0; + for (MatchHasTeam mht : me.getMatchHasTeamList()) + { + if (count == winner) + { + TournamentService.getInstance().setResult(tournament, mht, + MatchService.getInstance().getResultType("result.win").get()); + } + else + { + TournamentService.getInstance().setResult(tournament, mht, + MatchService.getInstance().getResultType("result.loss").get()); + } + count++; + } + } + + // Round should be over + assertTrue(TournamentService.getInstance().isRoundOver(tournament, + currentRound)); + + assertEquals((int) roundOver.get(roundOver.size() - 1), currentRound); + + TournamentService.getInstance().startNextRound(tournament); + if (!TournamentService.getInstance().isOver(tournament)) + { + currentRound++; + + Round r = tournament.getRoundList() + .get(tournament.getRoundList().size() - 1); + + assertFalse(r.getMatchEntryList().isEmpty()); + + retrievedRound = TournamentService.getInstance().getRound(r.getRoundPK()); + + assertNotNull(retrievedRound); + + assertFalse(retrievedRound.getMatchEntryList().isEmpty()); + } + else + { + + assertEquals(currentRound, expectedRounds); + } + assertTrue(currentRound <= expectedRounds, + "Unexpected amount of rounds.\nExpected: " + expectedRounds + + "\nFound: " + currentRound + "\n"); + } + TournamentService.getInstance().deleteTournament(tournament); + } } diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java index e492b6e..ab9005a 100644 --- a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/DoubleElimination.java @@ -6,6 +6,7 @@ import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; @ServiceProvider(service = TournamentInterface.class) public class DoubleElimination extends Elimination @@ -15,27 +16,26 @@ public DoubleElimination() super(2, false); } - public DoubleElimination(int winPoints, int lossPoints, int drawPoints, + public DoubleElimination(int winPoints, int lossPoints, int drawPoints, boolean pairAlikeRecords) { super(2, winPoints, lossPoints, drawPoints, pairAlikeRecords); } - - - - @Override + + @Override public String getName() { return "Double Elimination"; } @Override - public TournamentInterface createTournament(List teams, + public TournamentInterface createTournament(List teams, int winPoints, int lossPoints, int drawPoints) + throws TournamentSignupException { - DoubleElimination de = new DoubleElimination(winPoints, lossPoints, + DoubleElimination de = new DoubleElimination(winPoints, lossPoints, drawPoints, true); - de.teams.addAll(teams); + de.addTeams(teams); return de; } } diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java index b16c2e5..71f940d 100644 --- a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/Elimination.java @@ -14,7 +14,6 @@ import com.github.javydreamercsw.tournament.manager.AbstractTournament; import com.github.javydreamercsw.tournament.manager.api.Encounter; import com.github.javydreamercsw.tournament.manager.api.TeamInterface; -import com.github.javydreamercsw.tournament.manager.api.TournamentException; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; @@ -28,7 +27,6 @@ public abstract class Elimination extends AbstractTournament private static final Logger LOG = Logger.getLogger(Elimination.class.getName()); - private final int eliminations; /** * Provide eliminations and pairing option. Defaults to 3 points for a win, 0 @@ -39,8 +37,7 @@ public abstract class Elimination extends AbstractTournament */ public Elimination(int eliminations, boolean pairAlikeRecords) { - super(3, 0, 1, pairAlikeRecords); - this.eliminations = eliminations; + super(3, 0, 1, eliminations, pairAlikeRecords); } /** @@ -50,7 +47,6 @@ public Elimination(int eliminations, boolean pairAlikeRecords) public Elimination() { super(3, 0, 1, false); - this.eliminations = 1; } /** @@ -64,8 +60,7 @@ public Elimination() public Elimination(int eliminations, int winPoints, int lossPoints, int drawPoints, boolean pairAlikeRecords) { - super(winPoints, lossPoints, drawPoints, pairAlikeRecords); - this.eliminations = eliminations; + super(winPoints, lossPoints, drawPoints, eliminations, pairAlikeRecords); } @Override @@ -96,36 +91,6 @@ public Map getPairings() { if (pairingHistory.get(getRound()) == null) { - //Remove teams with loses from tournament - List toRemove - = new ArrayList<>(); - for (TeamInterface team : getActiveTeams()) - { - //Loss or draw gets you eliminated - if (team.getTeamMembers().get(0).getRecord().getLosses() - + team.getTeamMembers().get(0).getRecord() - .getDraws() >= eliminations) - { - toRemove.add(team); - } - } - List errors = new ArrayList<>(); - toRemove.forEach((t) -> - { - if (!errors.contains(t)) - { - try - { - LOG.log(Level.FINE, "Player: {0} is eliminated!", t.toString()); - removeTeam(t); - } - catch (TournamentException ex) - { - LOG.log(Level.FINE, null, ex); - errors.add(t); - } - } - }); if (pairAlikeRecords) { Map pairings @@ -247,6 +212,6 @@ public int getMinimumAmountOfRounds() * will be n= 2^r competitors. In the opening round, 2^r - n competitors * will get a bye. */ - return log(teams.size(), 2); + return log(getAmountOfTeams(), 2); } } diff --git a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java index 2ceecb5..208a15f 100644 --- a/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java +++ b/Elimination-Tournament/src/main/java/com/github/javydreamercsw/tournament/manager/elimination/tournament/SingleElimination.java @@ -6,6 +6,7 @@ import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; @ServiceProvider(service = TournamentInterface.class) public class SingleElimination extends Elimination @@ -31,11 +32,12 @@ public String getName() @Override public TournamentInterface createTournament(List teams, - int winPoints, int lossPoints, int drawPoints) + int winPoints, int lossPoints, int drawPoints) + throws TournamentSignupException { SingleElimination se = new SingleElimination(winPoints, lossPoints, drawPoints, true); - se.teams.addAll(teams); + se.addTeams(teams); return se; } } diff --git a/Swiss-Tournament/src/main/java/com/github/javydreamercsw/swiss/tournament/Swiss.java b/Swiss-Tournament/src/main/java/com/github/javydreamercsw/swiss/tournament/Swiss.java index d674f78..7a533ef 100644 --- a/Swiss-Tournament/src/main/java/com/github/javydreamercsw/swiss/tournament/Swiss.java +++ b/Swiss-Tournament/src/main/java/com/github/javydreamercsw/swiss/tournament/Swiss.java @@ -13,6 +13,7 @@ import com.github.javydreamercsw.tournament.manager.api.Encounter; import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; /** * Swiss tournament is an elimination tournament without eliminations. Just @@ -84,14 +85,14 @@ public int getMinimumAmountOfRounds() { * there will be n= 2^r competitors. In the opening round, 2^r - n * competitors will get a bye. */ - return log(teams.size(), 2); + return log(getAmountOfTeams(), 2); } @Override public TournamentInterface createTournament(List teams, - int winPoints, int lossPoints, int drawPoints) { + int winPoints, int lossPoints, int drawPoints) throws TournamentSignupException { Swiss swiss = new Swiss(winPoints, lossPoints, drawPoints); - swiss.teams.addAll(teams); + swiss.addTeams(teams); return swiss; } } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/AbstractTournament.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/AbstractTournament.java index d5af816..fc59b46 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/AbstractTournament.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/AbstractTournament.java @@ -6,6 +6,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -21,20 +22,22 @@ import com.github.javydreamercsw.tournament.manager.api.Encounter; import com.github.javydreamercsw.tournament.manager.api.EncounterResult; -import com.github.javydreamercsw.tournament.manager.api.NoShowListener; import com.github.javydreamercsw.tournament.manager.api.ResultListener; -import com.github.javydreamercsw.tournament.manager.api.RoundTimeListener; import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentException; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentListener; import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; import com.github.javydreamercsw.tournament.manager.api.Variables; - import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; public abstract class AbstractTournament implements TournamentInterface { private int format = 1; + /** + * Amount of non-wins to be eliminated. + */ + private final int eliminations; /** * Encounter id */ @@ -46,7 +49,7 @@ public abstract class AbstractTournament implements TournamentInterface /** * Teams that registered. */ - protected final List teams = new ArrayList<>(); + private final List teams = new ArrayList<>(); /** * Current list of active teams. This is an exact copy of teams before the * tournament starts. After it starts, teams that get eliminated or drop out @@ -79,12 +82,30 @@ public abstract class AbstractTournament implements TournamentInterface private final int drawPoints; private long no_show_time; private long round_time; - private final List noShowListeners - = new ArrayList<>(); - private final List roundTimeListeners + private final List listeners = new ArrayList<>(); protected final boolean pairAlikeRecords; private int id = -1; + + public AbstractTournament(int winPoints, int lossPoints, int drawPoints, + int eliminations, boolean pairAlikeRecords) + { + this.winPoints = winPoints; + this.lossPoints = lossPoints; + this.drawPoints = drawPoints; + this.pairAlikeRecords = pairAlikeRecords; + this.eliminations = eliminations; + } + + public AbstractTournament(int winPoints, int lossPoints, int drawPoints, + int eliminations) + { + this.winPoints = winPoints; + this.lossPoints = lossPoints; + this.drawPoints = drawPoints; + this.pairAlikeRecords = false; + this.eliminations = eliminations; + } public AbstractTournament(int winPoints, int lossPoints, int drawPoints, boolean pairAlikeRecords) @@ -93,6 +114,7 @@ public AbstractTournament(int winPoints, int lossPoints, int drawPoints, this.lossPoints = lossPoints; this.drawPoints = drawPoints; this.pairAlikeRecords = pairAlikeRecords; + this.eliminations = 1; } public AbstractTournament(int winPoints, int lossPoints, int drawPoints) @@ -101,6 +123,7 @@ public AbstractTournament(int winPoints, int lossPoints, int drawPoints) this.lossPoints = lossPoints; this.drawPoints = drawPoints; this.pairAlikeRecords = false; + this.eliminations = 1; } @Override @@ -258,6 +281,7 @@ public int getRandomWithExclusion(Random rnd, int start, int end, Integer[] excl @Override public void nextRound() throws TournamentException { + processRound(round); //Increase round round++; //Calculate pairings @@ -296,7 +320,7 @@ public TreeMap> getRankings() { TreeMap> rankings = new TreeMap<>((Integer o1, Integer o2) -> o2.compareTo(o1)); - teams.forEach((player) -> + getTeams().forEach((player) -> { int points = getPoints(player); if (rankings.get(points) == null) @@ -344,12 +368,47 @@ public void displayRankings() } } + @Override + public void processRound(int round) + { + //Remove teams with loses from tournament + List toRemove + = new ArrayList<>(); + for (TeamInterface team : getActiveTeams()) + { + //Loss or draw gets you eliminated + if (team.getTeamMembers().get(0).getRecord().getLosses() + + team.getTeamMembers().get(0).getRecord().getDraws() >= + getEliminations()) + { + toRemove.add(team); + } + } + List errors = new ArrayList<>(); + toRemove.forEach((t) -> + { + if (!errors.contains(t)) + { + try + { + LOG.log(Level.FINE, "Player: {0} is eliminated!", t.toString()); + removeTeam(t); + } + catch (TournamentException ex) + { + LOG.log(Level.FINE, null, ex); + errors.add(t); + } + } + }); + } + @Override public Map getPairings() { synchronized (getActiveTeams()) { - if (pairingHistory.get(getRound()) == null) + if (pairingHistory.get(getRound()) == null && getActiveTeams().size() > 1) { if (pairAlikeRecords) { @@ -458,7 +517,8 @@ public Map getPairings() { }; Random rnd = new Random(); - while (exclude.length < getActiveTeams().size() && getActiveTeams().size() > 1) + while (exclude.length < getActiveTeams().size() + && getActiveTeams().size() > 1) { int player1 = getRandomWithExclusion(rnd, 0, @@ -559,38 +619,20 @@ public long getRoundTime() } @Override - public void addNoShowListener(NoShowListener nsl) + public void addTournamentListener(TournamentListener rtl) { - if (!noShowListeners.contains(nsl)) + if (!listeners.contains(rtl)) { - noShowListeners.add(nsl); + listeners.add(rtl); } } @Override - public void removeNoShowListener(NoShowListener nsl) + public void removeTournamentListener(TournamentListener rtl) { - if (noShowListeners.contains(nsl)) + if (listeners.contains(rtl)) { - noShowListeners.remove(nsl); - } - } - - @Override - public void addRoundTimeListener(RoundTimeListener rtl) - { - if (!roundTimeListeners.contains(rtl)) - { - roundTimeListeners.add(rtl); - } - } - - @Override - public void removeRoundTimeListener(RoundTimeListener rtl) - { - if (roundTimeListeners.contains(rtl)) - { - roundTimeListeners.remove(rtl); + listeners.remove(rtl); } } @@ -633,6 +675,7 @@ public void updateResults(int encounterId, } break; case NO_SHOW: + case FORFEIT: //Fall thru case LOSS: //All others are winners @@ -766,4 +809,35 @@ protected void setFormat(int format) { this.format = format; } + + @Override + public void addTeams(List teams) + throws TournamentSignupException + { + for (TeamInterface team : teams) + { + addTeam(team); + } + } + + @Override + public List getTeams() + { + return Collections.unmodifiableList(teams); + } + + @Override + public List getListeners() + { + return Collections.unmodifiableList(listeners); + } + + /** + * @return the eliminations + */ + @Override + public int getEliminations() + { + return eliminations; + } } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/Team.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/Team.java index 9bcfdfb..7a37d68 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/Team.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/Team.java @@ -7,13 +7,12 @@ import org.openide.util.Lookup; -import de.gesundkrank.jskills.Rating; - import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; - import com.github.javydreamercsw.tournament.manager.api.standing.RecordInterface; +import de.gesundkrank.jskills.Rating; + /** * * @author Javier A. Ortiz Bultron @@ -23,13 +22,14 @@ public class Team extends de.gesundkrank.jskills.Team implements TeamInterface private static final long serialVersionUID = 8398904493889254598L; private final String name; private RecordInterface record = null; + private final int teamId; - public Team(List teamMembers) + public Team(int id, List teamMembers) { - this("", teamMembers); + this(id, "", teamMembers); } - public Team(String name, List teamMembers) + public Team(int id, String name, List teamMembers) { this.name = name; teamMembers.forEach(member -> @@ -37,11 +37,12 @@ public Team(String name, List teamMembers) put(member, new Rating(0, 0)); }); record = Lookup.getDefault().lookup(RecordInterface.class).getNewInstance(); + this.teamId = id; } - public Team(TournamentPlayerInterface p1) + public Team(int id, TournamentPlayerInterface p1) { - this("", Arrays.asList(p1)); + this(id, "", Arrays.asList(p1)); } /** @@ -91,16 +92,7 @@ public String toString() @Override public boolean hasMember(TournamentPlayerInterface member) { - boolean found = false; - for (TournamentPlayerInterface player : getTeamMembers()) - { - if (player.getName().equals(member.getName())) - { - found = true; - break; - } - } - return found; + return hasMember(member.getID()); } @Override @@ -110,8 +102,33 @@ public RecordInterface getRecord() } @Override - public TeamInterface createTeam(String name, List players) + public TeamInterface createTeam(int id, String name, + List players) { - return new Team(name, players); + return new Team(id, name, players); + } + + /** + * @return the teamId + */ + @Override + public int getTeamId() + { + return teamId; + } + + @Override + public boolean hasMember(int memberId) + { + boolean found = false; + for (TournamentPlayerInterface player : getTeamMembers()) + { + if (player.getID() == memberId) + { + found = true; + break; + } + } + return found; } } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/Encounter.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/Encounter.java index bfa98e9..babb269 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/Encounter.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/Encounter.java @@ -7,8 +7,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.github.javydreamercsw.tournament.manager.Team; - /** * Where to parties face off * @@ -16,7 +14,6 @@ */ public class Encounter { - private final Map results = new HashMap<>(); private final int id; @@ -46,23 +43,6 @@ public Encounter(int id, int format, TeamInterface team1, TeamInterface team2, this.format = format; } - /** - * Create an encounter between two players. - * - * @param id encounter id - * @param format encounter format - * @param team1 team 1 - * @param team2 team 2 - */ - public Encounter(int id, int format, TournamentPlayerInterface team1, - TournamentPlayerInterface team2) - { - results.put(new Team(team1), EncounterResult.UNDECIDED); - results.put(new Team(team2), EncounterResult.UNDECIDED); - this.id = id; - this.format = format; - } - public void updateResult(TeamInterface team, EncounterResult result) throws TournamentException { @@ -92,6 +72,7 @@ public void updateResult(TeamInterface team, p.getRecord().draw(); break; case NO_SHOW: + case FORFEIT: //Fall thru case LOSS: p.getRecord().loss(); @@ -156,11 +137,11 @@ public String toString() StringBuilder sb = new StringBuilder(); results.keySet().forEach((t) -> { - if (!sb.toString().isEmpty()) - { - sb.append(" vs. "); - } - sb.append(t.toString()); + if (!sb.toString().isEmpty()) + { + sb.append(" vs. "); + } + sb.append(t.toString()); }); return MessageFormat.format("Encounter {0} ({1})", id, sb.toString()); } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/EncounterResult.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/EncounterResult.java index 5ea1dc4..58b59c4 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/EncounterResult.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/EncounterResult.java @@ -6,5 +6,5 @@ */ public enum EncounterResult { - WIN, LOSS, DRAW, NO_SHOW, UNDECIDED; + WIN, LOSS, DRAW, NO_SHOW, FORFEIT, UNDECIDED; } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/NoShowListener.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/NoShowListener.java deleted file mode 100644 index 52b9f92..0000000 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/NoShowListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.javydreamercsw.tournament.manager.api; - -/** - * - * @author Javier A. Ortiz Bultron - */ -public interface NoShowListener { - - /** - * No show time is up! - */ - public void noshow(); -} diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/RoundTimeListener.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/RoundTimeListener.java deleted file mode 100644 index 062d78d..0000000 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/RoundTimeListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.javydreamercsw.tournament.manager.api; - -/** - * - * @author Javier A. Ortiz Bultron - */ -public interface RoundTimeListener { - - /** - * Round time is up! - */ - public void roundTimeOver(); -} diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TeamInterface.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TeamInterface.java index 2c7f761..f4d8020 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TeamInterface.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TeamInterface.java @@ -2,10 +2,10 @@ import java.util.List; -import de.gesundkrank.jskills.ITeam; - import com.github.javydreamercsw.tournament.manager.api.standing.RecordInterface; +import de.gesundkrank.jskills.ITeam; + /** * * @author Javier A. Ortiz Bultron @@ -30,6 +30,14 @@ public interface TeamInterface extends ITeam * @return true if found */ boolean hasMember(TournamentPlayerInterface member); + + /** + * Checks if a player is part of this team. + * + * @param memberId member id to look for. + * @return true if found + */ + boolean hasMember(int memberId); /** * Get the team's record. @@ -41,9 +49,18 @@ public interface TeamInterface extends ITeam /** * Create a team. * + * @param id Team id. * @param name Team name. * @param players Team members. * @return */ - TeamInterface createTeam(String name, List players); + TeamInterface createTeam(int id, String name, + List players); + + /** + * Get the team's id. + * + * @return ID for this team. + */ + public int getTeamId(); } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentInterface.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentInterface.java index db5fdad..06530c6 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentInterface.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentInterface.java @@ -6,7 +6,6 @@ import com.github.javydreamercsw.tournament.manager.Team; import com.github.javydreamercsw.tournament.manager.UIPlayer; - import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; /** @@ -14,250 +13,278 @@ * * @author Javier A. Ortiz Bultron */ -public interface TournamentInterface { - - /** - * Default BYE player. - */ - public final TeamInterface BYE = new Team(new UIPlayer("BYE", -1)); - - /** - * Get tournament name. - * - * @return tournament name - */ - public String getName(); - - /** - * Get the pairings for the current round. - * - * @return pairings for the current round. Null if there's a clear winner. - */ - public Map getPairings(); - - /** - * Get current round number. - * - * @return current round number - */ - public int getRound(); - - /** - * Get specific round. - * - * @param round round to look for - * @return round or null if not found. - */ - public Map getRound(int round); - - /** - * Get specific round. - * - * @param round round to look for - * @param encounters encounters to set to this round - */ - public void setRound(int round, Map encounters); - - /** - * Add player. - * - * @throws TournamentSignupException - * - * @param team TournamentPlayerInterface to add - */ - public void addTeam(TeamInterface team) - throws TournamentSignupException; - - /** - * Remove a player. - * - * @param team TournamentPlayerInterface to remove. - * @throws TournamentSignupException - * @throws TournamentException - */ - public void removeTeam(TeamInterface team) - throws TournamentSignupException, TournamentException; - - /** - * Advance the tournament to next round. - * - * @throws TournamentException if there can't be a next round. - */ - public void nextRound() throws TournamentException; - - /** - * Amount of active teams. - * - * @return active teams - */ - public int getAmountOfTeams(); - - /** - * Display pairings in text. - */ - public void showPairings(); - - /** - * Status of current round. - * - * @return true if complete (All encounters have a result) - */ - public boolean roundComplete(); - - /** - * Update results. - * - * @param encounterID encounter id to update results for - * @param team TournamentPlayerInterface - * @param result Encounter - * @throws TournamentException - */ - public void updateResults(int encounterID, - TeamInterface team, EncounterResult result) - throws TournamentException; - - /** - * Get the current rankings. - * - * @return current rankings - */ - public TreeMap> getRankings(); - - /** - * If no one drops, the amount of minimum rounds expected based on entries. - * - * @return amount of minimum rounds expected based on entries - */ - public int getMinimumAmountOfRounds(); - - /** - * Amount of points in the tournament. - * - * @param team player to get points from. - * @return points in the tournament - */ - public int getPoints(TeamInterface team); - - /** - * @return the winPoints - */ - public int getWinPoints(); - - /** - * @return the lossPoints - */ - public int getLossPoints(); - - /** - * @return the drawPoints - */ - public int getDrawPoints(); - - /** - * Get the winning team. - * - * @return winning team - */ - public TeamInterface getWinnerTeam(); - - /** - * Set the time allowed before no shows (milliseconds from pairings). - * - * @param time Date of no show. - */ - public void setNoShowTime(long time); - - /** - * Get the no show time. - * - * @return time allowed before no shows (milliseconds from pairings) - */ - public long getNoShowTime(); - - /** - * Set the time for the round to end (milliseconds from pairings). - * - * @param time round end time. - */ - public void setRoundTime(long time); - - /** - * Get the round time. - * - * @return time for the round to end (milliseconds from pairings) - */ - public long getRoundTime(); - - /** - * Add a no show listener. - * - * @param nsl no show listener - */ - public void addNoShowListener(NoShowListener nsl); - - /** - * Remove a no show listener. - * - * @param nsl no show listener - */ - public void removeNoShowListener(NoShowListener nsl); - - /** - * Add a round time listener. - * - * @param rtl round time listener - */ - public void addRoundTimeListener(RoundTimeListener rtl); - - /** - * Remove a round time listener. - * - * @param rtl round time listener - */ - public void removeRoundTimeListener(RoundTimeListener rtl); - - /** - * Check if the team has not been eliminated/dropped - * - * @param t team to check - * @return true if still active - */ - public boolean isTeamActive(TeamInterface t); - - /** - * List of teams still active. - * - * @return teams still active - */ - public List getActiveTeams(); - - /** - * Display rankings. - */ - public void displayRankings(); - - /** - * Return the ID for this tournament. - * - * @return ID for this tournament - */ - public int getId(); - - /** - * Set the ID for this tournament. - * - * @param id ID for this tournament - */ - public void setId(int id); - - /** - * Create a tournament. - * @param teams - * @param winPoints - * @param lossPoints - * @param drawPoints - * @return - */ - public TournamentInterface createTournament(List teams, - int winPoints, int lossPoints, int drawPoints); +public interface TournamentInterface +{ + + /** + * Default BYE player. + */ + public final TeamInterface BYE = new Team(-1, new UIPlayer("BYE", -1)); + + /** + * Get tournament name. + * + * @return tournament name + */ + public String getName(); + + /** + * Get the pairings for the current round. + * + * @return pairings for the current round. Null if there's a clear winner. + */ + public Map getPairings(); + + /** + * Get current round number. + * + * @return current round number + */ + public int getRound(); + + /** + * Get specific round. + * + * @param round round to look for + * @return round or null if not found. + */ + public Map getRound(int round); + + /** + * Get specific round. + * + * @param round round to look for + * @param encounters encounters to set to this round + */ + public void setRound(int round, Map encounters); + + /** + * Add teams. + * + * @throws TournamentSignupException + * + * @param teams Teams to add + */ + public void addTeams(List teams) + throws TournamentSignupException; + + /** + * Add team. + * + * @throws TournamentSignupException + * + * @param team TeamInterface to add + */ + public void addTeam(TeamInterface team) + throws TournamentSignupException; + + /** + * Remove a player. + * + * @param team TournamentPlayerInterface to remove. + * @throws TournamentSignupException + * @throws TournamentException + */ + public void removeTeam(TeamInterface team) + throws TournamentSignupException, TournamentException; + + /** + * Advance the tournament to next round. + * + * @throws TournamentException if there can't be a next round. + */ + public void nextRound() throws TournamentException; + + /** + * Amount of active teams. + * + * @return active teams + */ + public int getAmountOfTeams(); + + /** + * Display pairings in text. + */ + public void showPairings(); + + /** + * Status of current round. + * + * @return true if complete (All encounters have a result) + */ + public boolean roundComplete(); + + /** + * Update results. + * + * @param encounterID encounter id to update results for + * @param team TournamentPlayerInterface + * @param result Encounter + * @throws TournamentException + */ + public void updateResults(int encounterID, + TeamInterface team, EncounterResult result) + throws TournamentException; + + /** + * Get the current rankings. + * + * @return current rankings + */ + public TreeMap> getRankings(); + + /** + * If no one drops, the amount of minimum rounds expected based on entries. + * + * @return amount of minimum rounds expected based on entries + */ + public int getMinimumAmountOfRounds(); + + /** + * Amount of points in the tournament. + * + * @param team player to get points from. + * @return points in the tournament + */ + public int getPoints(TeamInterface team); + + /** + * @return the winPoints + */ + public int getWinPoints(); + + /** + * @return the lossPoints + */ + public int getLossPoints(); + + /** + * @return the drawPoints + */ + public int getDrawPoints(); + + /** + * Get the winning team. + * + * @return winning team + */ + public TeamInterface getWinnerTeam(); + + /** + * Set the time allowed before no shows (milliseconds from pairings). + * + * @param time Date of no show. + */ + public void setNoShowTime(long time); + + /** + * Get the no show time. + * + * @return time allowed before no shows (milliseconds from pairings) + */ + public long getNoShowTime(); + + /** + * Set the time for the round to end (milliseconds from pairings). + * + * @param time round end time. + */ + public void setRoundTime(long time); + + /** + * Get the round time. + * + * @return time for the round to end (milliseconds from pairings) + */ + public long getRoundTime(); + + /** + * Add a round time listener. + * + * @param tl round time listener + */ + public void addTournamentListener(TournamentListener tl); + + /** + * Remove a round time listener. + * + * @param tl round time listener + */ + public void removeTournamentListener(TournamentListener tl); + + /** + * Get listeners. + * + * @return Unmodifiable list of registered listeners. + */ + public List getListeners(); + + /** + * Check if the team has not been eliminated/dropped + * + * @param t team to check + * @return true if still active + */ + public boolean isTeamActive(TeamInterface t); + + /** + * List of teams still active. + * + * @return teams still active + */ + public List getActiveTeams(); + + /** + * Display rankings. + */ + public void displayRankings(); + + /** + * Return the ID for this tournament. + * + * @return ID for this tournament + */ + public int getId(); + + /** + * Set the ID for this tournament. + * + * @param id ID for this tournament + */ + public void setId(int id); + + /** + * Create a tournament. + * + * @param teams Teams to add + * @param winPoints Points per win + * @param lossPoints Poinst per loss + * @param drawPoints Points per draw + * @return Created tournament + * @throws TournamentSignupException if something goes wrong adding players. + */ + public TournamentInterface createTournament(List teams, + int winPoints, int lossPoints, int drawPoints) + throws TournamentSignupException; + + /** + * Get teams. + * + * @return Unmodifiable list of teams in this tournament. + */ + public List getTeams(); + + /** + * Process the round. Any eliminations and other changes to the pool of + * players must be done here. + * + * @param round Round to process. + */ + public void processRound(int round); + + /** + * Get the amount of non-wins to be eliminated from the tournament. + * @return amount of non-wins to be eliminated from the tournament + */ + public int getEliminations(); } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentListener.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentListener.java new file mode 100644 index 0000000..93545fe --- /dev/null +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/TournamentListener.java @@ -0,0 +1,31 @@ +package com.github.javydreamercsw.tournament.manager.api; + +/** + * + * @author Javier A. Ortiz Bultron + */ +public interface TournamentListener +{ + /** + * Round started! + * + * @param round Round number started. + */ + public void roundStart(int round); + + /** + * Round time is up! + */ + public void roundTimeOver(); + + /** + * Round ended. + * @param round Round number ended. + */ + public void roundOver(int round); + + /** + * No show time is up! + */ + public void noshow(); +} diff --git a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTest.java b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTest.java index 29d9f14..e8dc8ac 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTest.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTest.java @@ -14,12 +14,11 @@ import org.openide.util.Exceptions; import com.github.javydreamercsw.tournament.manager.api.EncounterResult; -import com.github.javydreamercsw.tournament.manager.api.NoShowListener; -import com.github.javydreamercsw.tournament.manager.api.RoundTimeListener; import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentException; import com.github.javydreamercsw.tournament.manager.api.TournamentInterface; import com.github.javydreamercsw.tournament.manager.signup.TournamentSignupException; +import com.github.javydreamercsw.tournament.manager.api.TournamentListener; /** * @@ -59,7 +58,7 @@ public void testGetRound() public void testAddPlayer() { System.out.println("addPlayer"); - TeamInterface team = new Team(new UIPlayer("Test", 1)); + TeamInterface team = new Team(1, new UIPlayer("Test", 1)); AbstractTournament instance = new AbstractTournamentImpl(); try { @@ -89,7 +88,7 @@ public void testAddPlayer() public void testRemovePlayer() { System.out.println("removePlayer"); - TeamInterface team = new Team(new UIPlayer("Test", 0)); + TeamInterface team = new Team(2, new UIPlayer("Test", 2)); AbstractTournament instance = new AbstractTournamentImpl(); boolean failure = false; try @@ -230,25 +229,13 @@ public long getRoundTime() } @Override - public void addNoShowListener(NoShowListener nsl) + public void addTournamentListener(TournamentListener rtl) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public void removeNoShowListener(NoShowListener nsl) - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void addRoundTimeListener(RoundTimeListener rtl) - { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void removeRoundTimeListener(RoundTimeListener rtl) + public void removeTournamentListener(TournamentListener rtl) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } diff --git a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java index bf68acb..3eea2b2 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/AbstractTournamentTester.java @@ -74,7 +74,7 @@ public void testGetPairings() throws TournamentSignupException { try { - tournament.addTeam(new Team(new UIPlayer(MessageFormat + tournament.addTeam(new Team(i, new UIPlayer(MessageFormat .format("Player #{0}", i), i))); } catch (TournamentSignupException ex) @@ -138,7 +138,7 @@ public void testGetPairings() throws TournamentSignupException { try { - tournament.addTeam(new Team(new UIPlayer(MessageFormat.format("Player #{0}", i), i))); + tournament.addTeam(new Team(i, new UIPlayer(MessageFormat.format("Player #{0}", i), i))); } catch (TournamentSignupException ex) { @@ -221,7 +221,7 @@ public void testSimulateTournament() { try { - tournament.addTeam(new Team( + tournament.addTeam(new Team(y, new UIPlayer(MessageFormat.format("Player #{0}", (y + 1)), y))); } catch (TournamentSignupException ex) @@ -237,6 +237,28 @@ public void testSimulateTournament() boolean ignore = false; while (tournament.getAmountOfTeams() > 1) { + //Random player drop + if (tournament.getActiveTeams().size() > 1 && random.nextBoolean()) + { + TeamInterface toDrop + = tournament.getActiveTeams().get(random + .nextInt(tournament.getAmountOfTeams())); + LOG.log(Level.INFO, "Player: {0} dropped!", toDrop.toString()); + try + { + tournament.removeTeam(toDrop); + } + catch (TournamentSignupException ex) + { + LOG.log(Level.SEVERE, null, ex); + fail(); + } + catch (TournamentException ex) + { + LOG.log(Level.SEVERE, null, ex); + fail(); + } + } try { tournament.nextRound(); @@ -270,7 +292,7 @@ public void testSimulateTournament() EncounterResult.values()[result]); } if (player1.equals(TournamentInterface.BYE) - || player2.equals(TournamentInterface.BYE) + || player2.equals(TournamentInterface.BYE) && tournament.getActiveTeams().size() == 1) { //Only one player left, we got a winner! @@ -285,28 +307,6 @@ public void testSimulateTournament() LOG.log(Level.SEVERE, null, ex); fail(); } - //Random player drop - if (tournament.getActiveTeams().size() > 1 && random.nextBoolean()) - { - TeamInterface toDrop - = tournament.getActiveTeams().get(random - .nextInt(tournament.getAmountOfTeams())); - LOG.log(Level.INFO, "Player: {0} dropped!", toDrop.toString()); - try - { - tournament.removeTeam(toDrop); - } - catch (TournamentSignupException ex) - { - LOG.log(Level.SEVERE, null, ex); - fail(); - } - catch (TournamentException ex) - { - LOG.log(Level.SEVERE, null, ex); - fail(); - } - } } if (!ignore) { diff --git a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/EncounterTest.java b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/EncounterTest.java index 808dd74..cbc1102 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/EncounterTest.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/EncounterTest.java @@ -29,8 +29,8 @@ public void testUpdateResult() try { System.out.println("updateResult"); - TeamInterface team1 = new Team(new UIPlayer("Player 1", 1)); - TeamInterface team2 = new Team(new UIPlayer("Player 2", 2)); + TeamInterface team1 = new Team(1, new UIPlayer("Player 1", 1)); + TeamInterface team2 = new Team(2, new UIPlayer("Player 2", 2)); Encounter instance = new Encounter(1, 1, team1, team2); instance.updateResult(team1, EncounterResult.WIN); instance.updateResult(team2, EncounterResult.LOSS); diff --git a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/TeamTest.java b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/TeamTest.java index 58d1e8b..d073c6a 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/TeamTest.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/tournament/manager/TeamTest.java @@ -23,10 +23,10 @@ public class TeamTest public void testGetTeamMembers() { System.out.println("getTeamMembers"); - Team instance = new Team(new UIPlayer("Test", 1)); + Team instance = new Team(1, new UIPlayer("Test", 1)); List result = instance.getTeamMembers(); assertEquals(1, result.size()); - instance = new Team(Arrays.asList(new UIPlayer("Test", 1), + instance = new Team(2, Arrays.asList(new UIPlayer("Test", 1), new UIPlayer("Player 2", 2))); result = instance.getTeamMembers(); assertEquals(2, result.size()); diff --git a/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java b/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java index d3ef0f8..d22ef22 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java @@ -50,7 +50,7 @@ public void testMatch() throws Exception UIPlayer p2 = new UIPlayer("Player 2", ++playerCount); TeamInterface[] teams = new TeamInterface[] { - new Team(p1), new Team(p2) + new Team(1, p1), new Team(2, p2) }; instance.addMatch("Test Match", teams); TrueSkillRankingProvider p = (TrueSkillRankingProvider) instance; @@ -79,7 +79,7 @@ public void testMatch() throws Exception UIPlayer p4 = new UIPlayer("Player 4", ++playerCount); teams = new TeamInterface[] { - new Team(p3), new Team(p4) + new Team(3, p3), new Team(4, p4) }; instance.addMatch("Test Match 2", teams); @@ -107,7 +107,7 @@ public void testMatch() throws Exception teams = new TeamInterface[] { - new Team(p1), new Team(p2), new Team(p3), new Team(p4) + new Team(1, p1), new Team(2, p2), new Team(3, p3), new Team(4, p4) }; instance.addMatch("Test Match 3", teams); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java index fc69484..c16893a 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java @@ -23,6 +23,7 @@ import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; import com.github.javydreamercsw.database.storage.db.server.TournamentService; +import com.github.javydreamercsw.tournament.manager.api.TournamentException; import com.github.javydreamercsw.tournament.manager.ui.MainLayout; import com.github.javydreamercsw.tournament.manager.ui.common.AbstractEditorDialog; import com.github.javydreamercsw.tournament.manager.ui.views.TMView; @@ -101,7 +102,7 @@ private String getTeamCount(Tournament t) { return Integer.toString(t.getTournamentHasTeamList().size()); } - + private String getFormat(Tournament t) { return t.getTournamentFormat().getFormatName(); @@ -123,19 +124,58 @@ private void addContent() .setWidth("6em"); grid.addColumn(new ComponentRenderer<>(this::createEditButton)) .setFlexGrow(0); + grid.addColumn(new ComponentRenderer<>(this::createControlButton)) + .setFlexGrow(0); grid.setSelectionMode(SelectionMode.NONE); container.add(header, grid); add(container); } - private Button createEditButton(Tournament category) + private Button createControlButton(Tournament tournament) + { + if (TournamentService.getInstance().hasStarted(tournament)) + { + Button view = new Button("Start", event -> + { + + }); + view.setIcon(new Icon("lumo", "view")); + view.addClassName("tournament__view"); + view.getElement().setAttribute("theme", "tertiary"); + return view; + } + else + { + Button start = new Button("Start", event -> + { + try + { + TournamentService.getInstance().startTournament(tournament); + } + catch (TournamentException ex) + { + Exceptions.printStackTrace(ex); + Notification.show( + "Unable to start tournament!", + 3000, Position.BOTTOM_START); + } + }); + start.setIcon(new Icon("lumo", "start")); + start.addClassName("tournament__start"); + start.getElement().setAttribute("theme", "tertiary"); + return start; + } + } + + private Button createEditButton(Tournament tournament) { - Button edit = new Button("Edit", event -> form.open(category, + Button edit = new Button("Edit", event -> form.open(tournament, AbstractEditorDialog.Operation.EDIT)); edit.setIcon(new Icon("lumo", "edit")); edit.addClassName("tournament__edit"); edit.getElement().setAttribute("theme", "tertiary"); + edit.setEnabled(!TournamentService.getInstance().hasStarted(tournament)); return edit; } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java index b3d495e..d6a9431 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java @@ -30,7 +30,6 @@ public class Welcome extends TMView { private static final long serialVersionUID = 1252548231807630022L; - private static boolean demo = false; static { @@ -42,10 +41,39 @@ public class Welcome extends TMView .lookup("java:comp/env/tm/JNDIDB"); DataBaseManager.setPersistenceUnitName(JNDIDB); - demo = (Boolean) context + boolean demo = (Boolean) context .lookup("java:comp/env/tm/demo"); - DataBaseManager.load(); + // Check if it's configured for demo + if (demo && PlayerService.getInstance().getAll().isEmpty()) + { + try + { + Notification.show( + "Loading demo data...", + 3000, Position.MIDDLE); + + DataBaseManager.loadDemoData(); + + Notification.show( + "Loading demo data done!", + 3000, Position.MIDDLE); + } + catch (Exception ex) + { + Notification.show( + "Error loading demo data!", + 3000, Position.MIDDLE); + Exceptions.printStackTrace(ex); + } + } + else + { + DataBaseManager.load(); + Notification.show( + "Loading data done!", + 3000, Position.MIDDLE); + } } catch (NamingException ex) { @@ -73,37 +101,6 @@ public void valueChanged(ValueChangeEvent e) { IGame gameAPI = cb.getValue(); saveValue(CURRENT_GAME, gameAPI.getName()); - - // Check if it's configured for demo - if (demo && PlayerService.getInstance().getAll().isEmpty()) - { - try - { - Notification.show( - "Loading demo data...", - 3000, Position.MIDDLE); - - DataBaseManager.loadDemoData(); - - Notification.show( - "Loading demo data done!", - 3000, Position.MIDDLE); - } - catch (Exception ex) - { - Notification.show( - "Error loading demo data!", - 3000, Position.MIDDLE); - Exceptions.printStackTrace(ex); - } - } - else - { - DataBaseManager.load(); - Notification.show( - "Loading data done!", - 3000, Position.MIDDLE); - } } }); cb.setEnabled(games.size() > 1); From a77cbd9e45dd7792a81cb8aaac80924d04719879 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 10 Dec 2018 10:53:30 -0600 Subject: [PATCH 18/25] Fix test that was falsely passing because data was loaded in the setup of the test case. --- .../database/storage/db/server/DataBaseManagerTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java index 0f7f102..a598604 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java @@ -26,11 +26,13 @@ public class DataBaseManagerTest extends AbstractServerTest @Test public void testLoadDemoData() throws Exception { + cleanDB(); //Load demo data DataBaseManager.loadDemoData(); assertFalse(PlayerService.getInstance().getAll().isEmpty()); assertFalse(TournamentService.getInstance().getAll().isEmpty()); + assertFalse(TournamentService.getInstance().getAllFormats().isEmpty()); assertFalse(MatchService.getInstance().getAll().isEmpty()); assertFalse(TeamService.getInstance().getAll().isEmpty()); assertFalse(RecordService.getInstance().getAll().isEmpty()); From 6263b04cd459930b0e0fc705dc696148558b8d1a Mon Sep 17 00:00:00 2001 From: Javier Ortiz Bultron Date: Mon, 10 Dec 2018 12:50:03 -0600 Subject: [PATCH 19/25] #22: Add Round time limit settings #23: Add sign up settings --- Database-Storage/DB.mwb | Bin 28933 -> 29435 bytes Database-Storage/DB.mwb.bak | Bin 28886 -> 29273 bytes Database-Storage/pom.xml | 6 + .../database/storage/db/Tournament.java | 170 ++++++++++++------ .../database/storage/db/TournamentFormat.java | 3 + .../storage/db/server/DataBaseManager.java | 98 +++++----- .../LocalDateTimeAttributeConverter.java | 22 +++ .../storage/db/server/TournamentService.java | 38 +++- .../db/server/TestTournamentFormat.java | 2 +- .../db/server/TournamentServiceTest.java | 20 ++- 10 files changed, 250 insertions(+), 109 deletions(-) create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/LocalDateTimeAttributeConverter.java diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index 4c366ebb958c73c9556cb7e66e31b55ae73d753a..237e92d8ca4d62f2491a4b13123dc613f7021b15 100644 GIT binary patch delta 27635 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 delta 27232 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 diff --git a/Database-Storage/DB.mwb.bak b/Database-Storage/DB.mwb.bak index bceba4fafbe475f5ce374bd1189d1f46a6e0b623..2c6ced3eacb056d52b80901224bfb9ab9527b86d 100644 GIT binary patch delta 28630 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

HN;l?%JQT&wjw~2DnO+!sgRUH$-T^c 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 tournamentHasTeamList; - private static final long serialVersionUID = 1L; - @EmbeddedId - protected RecordPK recordPK; @JoinColumn(name = "game_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java index a1d191b..d012b56 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java @@ -1,7 +1,6 @@ package com.github.javydreamercsw.database.storage.db; import java.io.Serializable; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -57,9 +56,6 @@ }) public class Tournament implements Serializable { - private static final long serialVersionUID = -6583090940281361773L; - @EmbeddedId - protected TournamentPK tournamentPK; @Basic(optional = false) @NotNull @Size(min = 1, max = 245) @@ -77,18 +73,31 @@ public class Tournament implements Serializable @NotNull @Column(name = "lossPoints") private int lossPoints; + @Basic(optional = false) + @NotNull @Column(name = "startDate") private LocalDateTime startDate; @Column(name = "endDate") private LocalDateTime endDate; + @Basic(optional = false) + @NotNull @Column(name = "signupDate") - private LocalDate signupDate; + private LocalDateTime signupDate; + @Basic(optional = false) + @NotNull @Column(name = "signupTimeLimit") - private Integer signupTimeLimit; + private int signupTimeLimit; + @Basic(optional = false) + @NotNull @Column(name = "roundTimeLimit") - private Integer roundTimeLimit; + private int roundTimeLimit; + @Basic(optional = false) + @NotNull @Column(name = "noShowTimeLimit") - private Integer noShowTimeLimit; + private int noShowTimeLimit; + private static final long serialVersionUID = -6583090940281361773L; + @EmbeddedId + protected TournamentPK tournamentPK; @JoinColumns( { @JoinColumn(name = "format_id", referencedColumnName = "id"), @@ -271,42 +280,42 @@ public void setEndDate(LocalDateTime endDate) this.endDate = endDate; } - public LocalDate getSignupDate() + public LocalDateTime getSignupDate() { return signupDate; } - public void setSignupDate(LocalDate signupDate) + public void setSignupDate(LocalDateTime signupDate) { this.signupDate = signupDate; } - public Integer getSignupTimeLimit() + public int getSignupTimeLimit() { return signupTimeLimit; } - public void setSignupTimeLimit(Integer signupTimeLimit) + public void setSignupTimeLimit(int signupTimeLimit) { this.signupTimeLimit = signupTimeLimit; } - public Integer getRoundTimeLimit() + public int getRoundTimeLimit() { return roundTimeLimit; } - public void setRoundTimeLimit(Integer roundTimeLimit) + public void setRoundTimeLimit(int roundTimeLimit) { this.roundTimeLimit = roundTimeLimit; } - public Integer getNoShowTimeLimit() + public int getNoShowTimeLimit() { return noShowTimeLimit; } - public void setNoShowTimeLimit(Integer noShowTimeLimit) + public void setNoShowTimeLimit(int noShowTimeLimit) { this.noShowTimeLimit = noShowTimeLimit; } From e536c8ddf67bc08fd1ebd0e344fb9247d61e0b69 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Wed, 19 Dec 2018 08:42:37 -0600 Subject: [PATCH 21/25] 1) Work to add tournament settings to UI. The time controls are not ready yet on the Vaadin side. 2) Some refactoring. --- TournamentManagerWeb/pom.xml | 10 +- .../FormatLabelGenerator.java | 4 +- .../MatchResultTypeLabelGenerator.java | 2 +- .../TournamentFormatLabelGenerator.java | 5 +- .../ui/views/matchlist/MatchEditorDialog.java | 4 +- .../ui/views/matchlist/ResultForm.java | 4 +- .../TournamentEditorDialog.java | 150 +++++++++++++++++- .../views/tournamentlist/TournamentList.java | 5 +- .../tournamentlist/TournamentManager.java | 51 ++++++ .../manager/ui/views/welcome/Welcome.java | 21 ++- 10 files changed, 229 insertions(+), 27 deletions(-) rename TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/{views/matchlist => common}/FormatLabelGenerator.java (65%) rename TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/{views/matchlist => common}/MatchResultTypeLabelGenerator.java (87%) rename TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/{views/tournamentlist => common}/TournamentFormatLabelGenerator.java (63%) create mode 100644 TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentManager.java diff --git a/TournamentManagerWeb/pom.xml b/TournamentManagerWeb/pom.xml index 86d67cf..e7c94b6 100755 --- a/TournamentManagerWeb/pom.xml +++ b/TournamentManagerWeb/pom.xml @@ -23,7 +23,7 @@ UTF-8 UTF-8 false - 11.0.1 + 12.0.3 9.4.11.v20180605 @@ -114,17 +114,13 @@ ${testng.version} test - + ${project.groupId} MTG ${project.version} - - org.vaadin.maxime - markdown-area - 1.0.2 - + mysql diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/FormatLabelGenerator.java similarity index 65% rename from TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java rename to TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/FormatLabelGenerator.java index 204a7ae..2c3ff5b 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/FormatLabelGenerator.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/FormatLabelGenerator.java @@ -1,9 +1,9 @@ -package com.github.javydreamercsw.tournament.manager.ui.views.matchlist; +package com.github.javydreamercsw.tournament.manager.ui.common; import com.github.javydreamercsw.database.storage.db.Format; import com.vaadin.flow.component.ItemLabelGenerator; -class FormatLabelGenerator implements ItemLabelGenerator +public class FormatLabelGenerator implements ItemLabelGenerator { private static final long serialVersionUID = -738603579674658479L; diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchResultTypeLabelGenerator.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/MatchResultTypeLabelGenerator.java similarity index 87% rename from TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchResultTypeLabelGenerator.java rename to TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/MatchResultTypeLabelGenerator.java index 02af836..7a86c28 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchResultTypeLabelGenerator.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/MatchResultTypeLabelGenerator.java @@ -1,4 +1,4 @@ -package com.github.javydreamercsw.tournament.manager.ui.views.matchlist; +package com.github.javydreamercsw.tournament.manager.ui.common; import org.openide.util.NbBundle; diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/TournamentFormatLabelGenerator.java similarity index 63% rename from TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java rename to TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/TournamentFormatLabelGenerator.java index 3f2573d..cd0b8d4 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentFormatLabelGenerator.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/common/TournamentFormatLabelGenerator.java @@ -1,9 +1,10 @@ -package com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist; +package com.github.javydreamercsw.tournament.manager.ui.common; import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.vaadin.flow.component.ItemLabelGenerator; -class TournamentFormatLabelGenerator implements ItemLabelGenerator +public class TournamentFormatLabelGenerator + implements ItemLabelGenerator { private static final long serialVersionUID = -738603579674658479L; diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java index 43334ef..bc9d70d 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/MatchEditorDialog.java @@ -15,6 +15,8 @@ */ package com.github.javydreamercsw.tournament.manager.ui.views.matchlist; +import com.github.javydreamercsw.tournament.manager.ui.common.FormatLabelGenerator; + import static com.github.javydreamercsw.tournament.manager.ui.views.TMView.CURRENT_GAME; import java.util.List; @@ -126,7 +128,7 @@ private void addFormat() .getAttribute(CURRENT_GAME)); cb.setLabel("Select a Format: "); - cb.setDataProvider(new ListDataProvider(formats)); + cb.setDataProvider(new ListDataProvider<>(formats)); cb.setItemLabelGenerator(new FormatLabelGenerator()); cb.setRequired(true); cb.setPreventInvalidInput(true); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java index 5b3dedb..71272be 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/matchlist/ResultForm.java @@ -1,5 +1,7 @@ package com.github.javydreamercsw.tournament.manager.ui.views.matchlist; +import com.github.javydreamercsw.tournament.manager.ui.common.MatchResultTypeLabelGenerator; + import org.openide.util.Exceptions; import com.github.javydreamercsw.database.storage.db.MatchEntry; @@ -33,7 +35,7 @@ public ResultForm(MatchList ml,Dialog dialog, MatchEntry me) resultGrid.addColumn(new ComponentRenderer<>((mht) -> { ComboBox cb = new ComboBox<>(); - cb.setDataProvider(new ListDataProvider(MatchService.getInstance().getResultTypes())); + cb.setDataProvider(new ListDataProvider<>(MatchService.getInstance().getResultTypes())); cb.setItemLabelGenerator(new MatchResultTypeLabelGenerator()); cb.setRequired(true); cb.setPreventInvalidInput(true); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java index 6068df5..ad8b416 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentEditorDialog.java @@ -15,6 +15,9 @@ */ package com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.function.BiConsumer; @@ -25,8 +28,13 @@ import com.github.javydreamercsw.database.storage.db.TournamentFormat; import com.github.javydreamercsw.database.storage.db.server.TournamentService; import com.github.javydreamercsw.tournament.manager.ui.common.AbstractEditorDialog; +import com.github.javydreamercsw.tournament.manager.ui.common.TournamentFormatLabelGenerator; import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.datepicker.DatePicker; import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.Result; +import com.vaadin.flow.data.binder.ValueContext; +import com.vaadin.flow.data.converter.Converter; import com.vaadin.flow.data.converter.StringToIntegerConverter; import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.data.validator.StringLengthValidator; @@ -42,6 +50,9 @@ public class TournamentEditorDialog extends AbstractEditorDialog private final TextField lossPoints = new TextField("Points per loss"); private final TextField drawPoints = new TextField("Points per draw"); private final ComboBox format = new ComboBox<>("Format"); + private final DatePicker signups = new DatePicker(); + private final ComboBox dateHour = new ComboBox<>(); + private final ComboBox dateMin = new ComboBox<>(); public TournamentEditorDialog(BiConsumer itemSaver, Consumer itemDeleter) @@ -53,6 +64,7 @@ public TournamentEditorDialog(BiConsumer itemSaver, addNameLossPoints(); addNameDrawPoints(); addTournamentFormat(); + addSettings(); } @Override @@ -61,6 +73,100 @@ protected void confirmDelete() doDelete(getCurrentItem()); } + private void addSettings() + { + List minutes = new ArrayList<>(); + for (int i = 1; i <= 60; i++) + { + minutes.add(i); + } + + LocalDateTime now = LocalDateTime.now(); + + dateHour.setPlaceholder("Hour"); + dateHour.setDataProvider(new ListDataProvider<>(minutes.subList(0, 24))); + if (getCurrentItem() != null) + { + dateHour.setValue(getCurrentItem().getSignupDate() == null ? null + : getCurrentItem().getSignupDate().getHour()); + } + dateHour.addValueChangeListener(event -> + { + updateSignupDate(); + }); + + dateMin.setPlaceholder("Minutes"); + dateMin.setDataProvider(new ListDataProvider<>(minutes)); + if (getCurrentItem() != null) + { + dateMin.setValue(getCurrentItem().getSignupDate() == null ? null + : getCurrentItem().getSignupDate().getMinute()); + } + dateMin.addValueChangeListener(event -> + { + updateSignupDate(); + }); + + signups.setMin(now.toLocalDate()); + signups.setPlaceholder("Date signups open."); + if (getCurrentItem() != null) + { + signups.setValue(getCurrentItem().getSignupDate() == null ? null + : getCurrentItem().getSignupDate().toLocalDate()); + } + getFormLayout().add(signups); + getFormLayout().add(dateHour); + getFormLayout().add(dateMin); + signups.addValueChangeListener(event -> + { + updateSignupDate(); + }); + getBinder().forField(signups) + .withConverter(new Converter() + { + private static final long serialVersionUID = -4231752474899375998L; + + @Override + public Result convertToModel(LocalDate value, ValueContext context) + { + LocalTime lt + = LocalTime.of(dateHour.getValue() == null ? 0 + : dateHour.getValue(), + dateMin.getValue() == null ? 0 + : dateMin.getValue()); + return Result.ok(LocalDateTime.of(value, lt)); + } + + @Override + public LocalDate convertToPresentation(LocalDateTime value, ValueContext context) + { + if (value != null) + { + dateHour.setValue(value.getHour()); + dateMin.setValue(value.getMinute()); + } + return value == null ? null : value.toLocalDate(); + } + }) + .bind(Tournament::getSignupDate, Tournament::setSignupDate); + + ComboBox signupLength = new ComboBox<>(); + signupLength.setPlaceholder("Signup time limit."); + signupLength.setDataProvider(new ListDataProvider<>(minutes)); + + getFormLayout().add(signupLength); + getBinder().forField(signupLength) + .bind(Tournament::getSignupTimeLimit, Tournament::setSignupTimeLimit); + + ComboBox roundLength = new ComboBox<>(); + roundLength.setPlaceholder("Round time limit."); + roundLength.setDataProvider(new ListDataProvider<>(minutes)); + + getFormLayout().add(roundLength); + getBinder().forField(roundLength) + .bind(Tournament::getRoundTimeLimit, Tournament::setRoundTimeLimit); + } + private void addNameField() { getFormLayout().add(tournamentNameField); @@ -72,12 +178,20 @@ private void addNameField() 3, null)) .withValidator(name -> { - List results - = TournamentService.getInstance().findTournaments(name); - return results.isEmpty() - || (results.size() == 1 - && getCurrentItem().getTournamentPK() - .equals(results.get(0).getTournamentPK())); + boolean valid = true; + for (Tournament t + : TournamentService.getInstance().findTournaments(name)) + { + if (t.getName().equals(name) + && !t.getTournamentPK() + .equals(getCurrentItem().getTournamentPK())) + { + // Same name with different id. + valid = false; + break; + } + } + return valid; }, "Tournament name must be unique") .bind(Tournament::getName, Tournament::setName); @@ -126,7 +240,7 @@ private void addTournamentFormat() List formats = new ArrayList<>(); formats.addAll(TournamentService.getInstance().getFormats()); - format.setDataProvider(new ListDataProvider(formats)); + format.setDataProvider(new ListDataProvider<>(formats)); format.setItemLabelGenerator(new TournamentFormatLabelGenerator()); format.setRequired(true); format.setPreventInvalidInput(true); @@ -160,8 +274,30 @@ protected boolean isValid() return false; } +// if (getCurrentItem().getNoShowTimeLimit() == null +// || (getCurrentItem().getNoShowTimeLimit().getHour() +// + getCurrentItem().getNoShowTimeLimit().getMinute() == 0)) +// { +// // Must be valid +// return false; +// } // All are zero return getCurrentItem().getDrawPoints() + getCurrentItem().getLossPoints() + getCurrentItem().getWinPoints() > 0; } + + private void updateSignupDate() + { +// if (signups.getValue() != null +// && dateHour.getValue() != null +// && dateMin.getValue() != null) +// { +// LocalDateTime ldt = LocalDateTime.of(signups.getValue().getYear(), +// signups.getValue().getMonthValue(), +// signups.getValue().getDayOfMonth(), +// dateHour.getValue(), dateMin.getValue()); +// System.out.println("New Date: " + ldt); +// getCurrentItem().setSignupDate(ldt); +// } + } } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java index c16893a..7c9f135 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentList.java @@ -136,9 +136,10 @@ private Button createControlButton(Tournament tournament) { if (TournamentService.getInstance().hasStarted(tournament)) { - Button view = new Button("Start", event -> + Button view = new Button("Manage", event -> { - + TournamentManager tm = new TournamentManager(tournament); + tm.open(); }); view.setIcon(new Icon("lumo", "view")); view.addClassName("tournament__view"); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentManager.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentManager.java new file mode 100644 index 0000000..15dc26e --- /dev/null +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/tournamentlist/TournamentManager.java @@ -0,0 +1,51 @@ +package com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist; + +import java.util.ArrayList; +import java.util.List; + +import com.github.javydreamercsw.database.storage.db.Tournament; +import com.github.javydreamercsw.database.storage.db.TournamentPK; +import com.github.javydreamercsw.database.storage.db.server.TournamentService; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.dialog.Dialog; +import com.vaadin.flow.component.html.Label; +import com.vaadin.flow.component.html.NativeButton; +import com.vaadin.flow.data.provider.ListDataProvider; + +public class TournamentManager extends Dialog +{ + private static final long serialVersionUID = -9151481749063166946L; + private final TournamentPK id; + private final Label title; + private final ComboBox cb = new ComboBox<>("Round"); + + public TournamentManager(Tournament tournament) + { + this.id = tournament.getTournamentPK(); + setSizeFull(); + setCloseOnEsc(true); + setCloseOnOutsideClick(false); + title = new Label("Tournament: " + tournament.getName()); + add(title); + cb.addValueChangeListener(listener -> update()); + add(cb); + + NativeButton closeButton = new NativeButton("Close", event -> + { + close(); + }); + add(closeButton); + } + + private void update() + { + Tournament t = TournamentService.getInstance().findTournament(id); + List rounds = new ArrayList<>(); + for (int i = 1; i <= t.getRoundList().size(); i++) + { + rounds.add(i); + } + cb.setDataProvider(new ListDataProvider<>(rounds)); + cb.setValue(t.getRoundList().size()); + } +} diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java index d6a9431..6fe3060 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/welcome/Welcome.java @@ -8,7 +8,6 @@ import org.openide.util.Exceptions; import org.openide.util.Lookup; -import org.vaadin.maxime.MarkdownArea; import com.github.javydreamercsw.database.storage.db.server.DataBaseManager; import com.github.javydreamercsw.database.storage.db.server.PlayerService; @@ -21,6 +20,7 @@ import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.notification.Notification.Position; +import com.vaadin.flow.component.textfield.TextArea; import com.vaadin.flow.data.provider.ListDataProvider; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; @@ -69,7 +69,17 @@ public class Welcome extends TMView } else { - DataBaseManager.load(); + try + { + DataBaseManager.load(); + } + catch (Exception ex) + { + Notification.show( + "Error loading demo data!", + 3000, Position.MIDDLE); + Exceptions.printStackTrace(ex); + } Notification.show( "Loading data done!", 3000, Position.MIDDLE); @@ -77,6 +87,9 @@ public class Welcome extends TMView } catch (NamingException ex) { + Notification.show( + "Error loading demo data!", + 3000, Position.MIDDLE); Exceptions.printStackTrace(ex); } } @@ -85,12 +98,12 @@ public Welcome() { addClassName("welcome-list"); setDefaultHorizontalComponentAlignment(Alignment.STRETCH); - MarkdownArea mda = new MarkdownArea("Hello world !"); + TextArea mda = new TextArea("Hello world !"); List games = new ArrayList<>(); games.addAll(Lookup.getDefault().lookupAll(IGame.class)); ComboBox cb = new ComboBox<>(); cb.setLabel("Select a Game: "); - cb.setDataProvider(new ListDataProvider(games)); + cb.setDataProvider(new ListDataProvider<>(games)); cb.setItemLabelGenerator(new GameLabelGenerator()); cb.addValueChangeListener(new ValueChangeListener() { From ace0a454d0f5a6483f03fdab1aa55ce4ca5a5b33 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Wed, 26 Dec 2018 14:11:51 -0600 Subject: [PATCH 22/25] Add mean and standard deviation attributes for team. --- Database-Storage/DB.mwb | Bin 29418 -> 29784 bytes Database-Storage/DB.mwb.bak | Bin 29423 -> 29418 bytes .../database/storage/db/Team.java | 25 ++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index b4730801694147246a4af5d14a35ff30744828bf..f1b70d89bbcc69a2b74e0abce6d3f2e70359e2fd 100644 GIT binary patch literal 29784 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 F{{@QGU7P>_ literal 29418 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 MigF$S^pmM_K`0K0RsaA1 diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java index bab914a..093d7cc 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java @@ -37,6 +37,11 @@ public class Team implements Serializable @Size(max = 245) @Column(name = "name") private String name; + // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation + @Column(name = "mean") + private Double mean; + @Column(name = "sd") + private Double sd; private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @@ -149,4 +154,24 @@ public void setName(String name) { this.name = name; } + + public Double getMean() + { + return mean; + } + + public void setMean(Double mean) + { + this.mean = mean; + } + + public Double getSd() + { + return sd; + } + + public void setSd(Double sd) + { + this.sd = sd; + } } From 221dc17647bd58c4b2c7c4ad957db77c6e60738e Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Wed, 26 Dec 2018 16:11:26 -0600 Subject: [PATCH 23/25] Process and update rankings when a result is processed. --- Database-Storage/DB.mwb | Bin 29784 -> 31629 bytes Database-Storage/DB.mwb.bak | Bin 29418 -> 31664 bytes .../database/storage/db/Format.java | 58 ++-- .../database/storage/db/Game.java | 55 ++-- .../database/storage/db/Team.java | 28 +- .../storage/db/TeamHasFormatRecord.java | 164 +++++++++++ .../storage/db/TeamHasFormatRecordPK.java | 112 ++++++++ .../db/controller/FormatJpaController.java | 67 +++++ .../TeamHasFormatRecordJpaController.java | 257 ++++++++++++++++++ .../db/controller/TeamJpaController.java | 69 ++++- .../storage/db/server/DataBaseManager.java | 19 +- .../storage/db/server/FormatService.java | 6 +- .../storage/db/server/MatchService.java | 185 +++++++++++++ .../storage/db/server/PlayerService.java | 12 +- .../storage/db/server/TeamService.java | 74 +++++ .../main/resources/META-INF/persistence.xml | 3 + .../db/server/DataBaseManagerTest.java | 22 +- .../storage/db/server/MatchServiceTest.java | 20 +- .../tournament/manager/UIPlayer.java | 11 +- .../manager/api/standing/RankingProvider.java | 5 +- .../trueskill/TrueSkillRankingProvider.java | 11 +- .../TrueSkillRankingProviderNGTest.java | 8 +- .../tournament/manager/ui/MainLayout.java | 6 + .../ui/views/rankings/RankingList.java | 92 +++++++ 24 files changed, 1170 insertions(+), 114 deletions(-) create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecordPK.java create mode 100644 Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamHasFormatRecordJpaController.java create mode 100644 TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index f1b70d89bbcc69a2b74e0abce6d3f2e70359e2fd..2f912df88f1fc108a861daffb4797524005c13c6 100644 GIT binary patch literal 31629 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 literal 29784 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 F{{@QGU7P>_ diff --git a/Database-Storage/DB.mwb.bak b/Database-Storage/DB.mwb.bak index b4730801694147246a4af5d14a35ff30744828bf..dc7b8273c0f64335af9972fa463cb1b8204985ea 100644 GIT binary patch delta 30252 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 delta 28033 zcmZs?V{j$i8}=I~6Wg|J+fH^e$wU*|){gBR+cUA9Ol(bT+qTX;|M#s^=fnBdy;fCM zSNFZ@zOLW3R_zn`=>a&NssbbwCKwnP92h`8TIs~&0r}7j49sg6CJ|2r1Hu}$v2yVi zm?xW%L>mc(0DwkMw7~~@asQb3dZF`^&i%YP`r6Awrl}YO?H!y>&KP^~>wMg4gaL2% z9od9L><%kjcKbl5K<(na`gd>-BAm%EYWQE`xU zOC)toGKP$dAGihVNWULFNBkwIKcW5XxqU|Pa(}|agK6>a6YSqRQ-|Yp=LmhQRn76* z3ajinYB9GG8+rRT>t;)HreaHQf-XIrb%_@n@~FqRvJMWKRF=9MGv3hJ>@TA|7#e4< zx`8(&y9*X~d*fe?6FVn&z}K}`k>~fkyotkZ2lijxEZRU3Lw|p#-Y1vr_d9p&4;3Io zzoG8s0>ajN*fMI^El2gHi23B3A@!Z{3l2v2>&g+V`<>(jDu&n7WB$;i2+d78?i_L=UT14u1Ud(ppE}qxt z_x&rt96=yLtFxn(!4$d71t$ht4#FL2xVpQa8CYa%DREzydBSW6*}qQ<~QEXj<+X)m1ENuTTHoCTDJ$D zXQ9B#Hu5A>=n0zpCIjeeGBeaN#$l&P9$@^T$Vt2Ow8*VdX@3`91RcKiPBLtCU zZX#ji@1B7P@Nb+{8Q-%wIzGDy6=SS$b2fpj1q3AL`@T({Y*mBQb+2?D0{jh7Hp{_|~uP_1TKrled5dZ!aQP zdprL*|4-87C&GlPnpBWO+Q5@R*U)x z&B%q5PekX#=jE+h%hfFg$AV>AMOim%j*G>fL*U)|R)z+&*IctV?rLGdf>RN#Gi%S| z>wKbFu=nJ&qHKY4)_jI)fvd)8_s9Ro--w}4Yxmd7;+Is^N)blW?UTEc-TPTLW)u|V zX=dQ3Y4o(CmUhwb#p2*eD9*WU4-T;4_Pq8EEE?3G#x#74AJEeGsTA+HH^5JB$UaNf zj&?1Hk0{1AbdBpCbT>*}fsSEtiT)%z*hRFxS@64+M}A!(TXVglwT0=j3j1jMcJ6(y zcQlJEp?3T?3Oqq@3BMe*lX@xz_ifCwCF5UP!T3l%W|P68x}PQz^xSdi1Oz}pU7hh> z^D-|fsjxC8=L9_{7~Cut42@N>krGCA%I755IdCp2s7RvMN~%|_a2u_H_Pbgw1w8Q{ zi-h>k@f%`HV*h>W(_$oWDo62ug)DswHAItTRZD(&uPrrDN4Bdb#6U<#9(P=s@J)vd zjqE0Vw7zovEo|`C0?2C1F$U}p5Ch|L?{@QJ(Z{W}~wWM1Q!tt)B-Gc=}nAV5B#Zr)p= zsAvE{N=Sq{>n+WzPFnnsPz$lMDC*go-AMxfZ7u$xHeYpIF&U1Smj~nxgNF5-UrUS` zhY7DEL|3WW%7vNBI5iap%7>v-lF+jGHXIiGEYXmeqS5pQ-QTca+Sa#*yPZ(`po&rv zLM~9EXPO|?E2mc03wKC1H_|yf`g?!@GY$#fONfS$2J^N`woN+OAaJJ zjPjP}RmR2q_fmaE!x4_|f+9d3RoP|l%5Z=xF0>LShEX3IYKZi;I6bSNg?U>F`!Rf2 z5oEu&GOsdg@fPYb;(NDFf6ndY2d)YuCM>UzirR68Qdo!24^6so1jQaOr6!kX4eB} zU7R4EpeZFM6CPfkiyw!90$^gU^lbIB``BGr8+-!?cNzzOLPJ}7+FM0G=9hus#vXq#@hqXq zH(9Su*9!fmm=j3Pnb0D61+q%(g-@2hJal%xrHP0*?L0*186tz3vK)p_=H;pSf84p8 z6rvX%TO3H{l~S_tsj0tdzrlq#CZv9XE<*6ws%m_N)dx;Uz&IDS`z}h2NkW12w%OpkFT--r2A6 z_*ZAOqfg)U`IP=0ak2AuGhfrBIB$!KO5zi=i+xf2o71Di<9PV|@cG3)UFxoM`V1tfSHL#6?hjU+8Fn@9RWM}Te zaCU#+vo5=8GuM4lWdChOUAmZ@(kE;}vd|%FEGR}60i>aOM9|2H zrIAf|eG-9C0${($`>65jTg3{H$FH!GeQ5ehOGx?kD?Mj&F%als{y+@=mNt4@+1b)T z726+Pb;jf4)cP`B!{YDU{VCJ(GBM?^Go?)PVfivh4?N?Fzk50F_LddX|C4ffeROAl zM>l5{3@%N_ej;{0K>CBouqJO*hc7yt#DS|tALjHJMIqg}HA`bhY1()p`;SjB+@=W{ zFs^QO`CRo!rFJm(PYumc3L{e~vE_95r3lgVggy)v&XzaaM#XvDU~IEUoFQq-NyHNu zcryV26fi=3v?uu{upGZ}KL0>KWYIc9%UOGLV`^l>fyMBB&7q8^g+i!pZ^ z!}a~#UYx#z0HMRiqDf%e!!F7FF=2zK7OlR6l=6VwDPn+p@_ICAAu_Oj9tvAON?g-k zyXE4~?az;fQ~H{U&T7~ipBwg4;JQFn2h+p(q~!Vav`lv%PlnbI5BAW~TE2%U%v!PE z1qGh1v@A>tCmm%piZ+bzA{iy?gbQ4tMp-0z->5uHI90F&WyK}~-g#bH+aAaXkr}8B zms{pE$-9>c9+aVMc5djip)8TD{Q2&7^I3V;l6By8XB?O7ykHTsb=bo9js!VzC}eN6 z`QGM?bIV6091zi-R0ZUG3w04V1$Ex)I#^P{vC^zXg6UyO@$+Ja>n-0=gAtM z|4SADraHG!(KwsBKw!ZdF^;gq6BRI@nrLh7zzAo1*(s)>;VJsSd~yEIpId9Ip$>#j zriZ*P7hQ)xfd{7UxSP4tZ=MO$CfN_T`NIm|nKzG`zAm0W{y9$UBPU{E3YC7gDWH5@Fw1zzsQ|B~|_U9@j zJv}5YgQ|beToLwvfUN#A7iZ`n`|eoR$u+W~$hrjCnaRBAHj80R64!_zg7UH~LlR>fgdr`}FHS@1fVFnNR%!XKRe1*Sd`Z21ERP4>yV0{fgdm(T%4S9{%Acqw zi-Y~NnqrQyHE9)2`7TQZRRsFAwsF26ZxX{JY}fDpeK$?xc<2%3mjqC=%-#uXUJdf0 zh`qJCYcavMuLTVevcDL5yf9JNDbD?Ci5Z}31rXZ^gtyiJ^sXVbI?(@C0zf-pRcK<( z*UU|X%f4=;ELt&~ciTK%#begcm#C5w4vRD{ZPP}Js+&ieM}M(=mcMS9Nc<@({}NK( z7r;;a8w)}N5~|Dd3FFh6~?TpV)1tJQ7$ zDJRpYI_KbS(|JxIQA*?#k=a~5)d_c#6;)32(8CUyK$T(%+a2QaVhN!F*e`5JXODIB zL|py+E0`KSs;3>A6m61Bl$d2Y|yLn_tBA?ZjegZ4$Vm6EmOG{aW?=gpR zCu&Ps7cqx2`@U=7@;I0+U=G3N_5J3jQreJ%r+^;IQ@ssVeM;?nzBIip&{@16v_FY% z5$r0^z-gGtrLPdpEEc6D?-h_Dl}{x4#{Zh7zAv58zO2d}H$Rw}GHK;?m zcjrgIar?cMPLzs}Hj|u*1r|IkYK$UD2hZ;mQ}%BEr9|bkA2fOZMdi=sTG^w9s1?=2^& zEfw`AlA8$eSB@-`;C0*FHxN{wJ7@SwPSX=KL$1^U!!q^9!ye4VwPjdrBjEF@7)w(M zp~+mpSSZ0WZC!`FO8Or3*|{>(i_{yIhB5pA4iB;WvxC2;BV}h*F#^Z+jx(dB())v) zgW7KQy-ce*XP#=t?*$Du)X&e}{^=nl_NOX&#if`vYN5;2@I|z#NmEq1jGcpUM?ap5 z!=*c*u?7p!f4A=pN2Hq&OtD*Sp+7G#8Z~k!5{$=d!z;C5^cF6WAP-AT%exIaz<^FP zX96t*=Z6A`AD4JM3kvN}u*&6WJqh9+cX}yRKhu*#%1*QXa~yw+a9baN$+3GG=XNKB zQLM4<5M~Kw4z{q210BWi(J#jx7v>)46f!R$ddBTBppwvd2WW$Dm^-XOWOrXN=>1tu zsO!-7-6OB&@hvMF!;R4PWk*9|RP0sLUf@!dfMRPFJflrkSzQtyM-=y7cT)gq-khbi zd5qSp#&x^MDbBkBk2THlAfd49cS5@)RuOA2ACr-%cMDQ z)jlFDN2^c_l|f1T^;l_w)RvLIcpYMzAMLblR!zIm=}6L~?=jrccS5|7%Ci^@EvHm= zA}|sk#}-+#12b6mw1!#X%Y<|jH8){NR|0&g8=T-TmMK1Blb}nX)vrW6oM&-b@I6*i zboQNOH)&M%pkYM_4SFqf4#Y^ED@P>Y^iN&HH5-r9%&s(ZMD!C%T?Sm~=MXYEoYjJ> z#fTBbkQnd|q|IBuWZ67UlVn+$>BK_u#XWtrGj4+*4M8K$+{T2&(PH%!*)42k2av1- z)nvmK`bkx)l}hBjf3p&yM9RK z(L2qpj~yjaOGcfOY!}2~yRaa%u-#;vF-!A=;wjw7UorDKaDM|$v4UB9B|b@Z#+VHiB@7PvIa3dSZ2#-h{MK8if@ z#odz>@66qwkBZ{;ktJjGhtNA*IroS{IP8+d9$B+9;_6=NrC$}<8xlf(228A`ZjQqg zwg~?iLLX0gMpAqala1}r-dz&;VKcm=xF6&ch@u^u^qye_qu|R7O{T62#K<;S+AHy)mL;MBPIxU&M1or~NRcpPFQ`HXCz3y*0#V=kW^)nTF zmC~|^ol#g8w~i5>#qBD=LeUrcYFfHj4EDdZh$p`PHF?|W#U`WDcFNJ`a98!p0Tk-7 z-Q0sYoXlhJAS<0~OMJZtK1K7t66^1*wRC)L+SQUFI{;reLCb`bhi7?za`w`?`PP~p zE=4z5VeJNmBuOqkK>x4ikiW4m>-kS}0Ft|0X1JefP#mU@`~*ji*rvP@|L##S;#}Q% zM>p<0Ep?qmqdYfdC@YuxNxzinzzVsUiT?=>N!jkWhl{Q;rmE97 zrnL$Rq&nxCxTSvkMg1d$n$wk5;mLT5JMo&MJE{APVV#=KToX5h2u_)(?G%yYI{sW0>IQ{Y`J zI5JY0K)KNV2rb++5pEPu&Hn*v2ssIz0LM9pmO?j=h{^ct!*0uN3LhQ+uIdq&iB`oF zSo}grv?gd8(*WB_V@Y_bn?!>S0)}EBdeF@1+{LB)?J%1(VIH@!0ORdAo$LNvxGk7W z*I=)?jM99(q9k$pw$w#%pkrn*ATW@U??5ziXZEW}0idZ1Q1i%-^49b*ZzOQs(o~DL zo{rI)kq1b1$w!4H2yW!${!eIdUB}Pp=E%t>G$xVK&PlN;1v0G zO&UYAiB}QpX1@?;QC`v$uwGGLKhqh<$GRMz8Gw(lJ={g-6i`}nSNgKvB$s-#Zw_md z7MSeXeWSlaVo(_oNNv%#8)@>}w4_gaV(WcqUECz4>0Ge<W$1~uCv^sfDOl!6Sc$j>O@y5lY609aHEX_pX$v`T=3}_F)xjfe$3AsJ z{P09fiqzyjzDXI-x~b_Yz~|#KT4B%EXeBq>jwm<}eC+j5Ju6FO#EJE;aV$U^mb#`hLugEq=OZ#`1&u_pau~-#*jA{)RrQzx*Y<~}{PI3Vo?oFhN zOUJeqFm#nE|8dvQmBw<-{M_ITb4hZ?8nMa80P3nLZM#^Uc2*}ysh6xm(ZK5pug;sq z=II{y&Dj5*O>!6%SWFHPFM4_qiM|a$7NaFj`rG90aJKld;u;Fj2t#vYhrF%ELm)yubVG9T}5|kW%cPk zQx||`u6lHQWOZaSIS+VAOeajwNAs<%ZtU4NayHNJjLGKMpJ)7^hxPEc4X9d_zoc(F z6T5sYZCOR~NowlV6&qYNvg3@Y38%XXf@>bjT9F{PT)~aZCsk%oq=mAVB@2Qf90h)B zR75+8aMG%mhdM)k^tiMOxNnw+VnFkaki4!>sHzv`sA6;+V606c(vEE}SL11v-axYe z6kP_|%s&WHRpYw>imI*W0kQ3qbXjxdYERpor~GurkvTTA`ZJRz`vzPm)vC|*Dogsg z)srTKx@A+mGF=OZ=?d6TbO+z)b%7D|(m#V-U+8}+vf=&;V;PDGXh^6Xtlc&hNLD5URq^Wv#=p| zGYkKTTeff^P4wN=jU6v|gx(|MKvoF%3RN3=#|UCcY9rf*$!dhBf_($4f?XORd>2R8s+>NRn~>}VaMN}wDmXKswapaa|?-6oT)2O%!oXSWU+i#%WodGNe)k&W6K^SKZpEY4+}vA~DJ0t)E| zV==)i)b*r#s?e@o>ofoO1yeAIAVP$!#XjZJU$f%ps@KA}l75p+hG8rs2#H^ z+}&BeR@JI%b=obc)OEr_@!0|4lTZOQ0XX*A$G^*&^`wT${@&nz8Ed1iIG@9Yg8KN% z)9;L|5_stV^DIdaR5>F_(C=-R<#8x9XKlN@PU>3+ZRBOVFA0w5U1X~}0o%*oJ+Pq> zaK5|*nE@vuAb9q`CB7i6WOIt*X*$4v0RPl`>L0+jr6<>tJP(a9{80bH4iuDjZyOLU zGzXB7==l-);S%J%KFd_WnXp?%&|@iu;`XL6LD2KMkcStGf1de23=?rMYa9fI9g9lZ z^?t)6C8)qn6d#Sv_#!aOKzphZ*Ro5rV9}y*|UDypz42dgCSFo zwW0;oz;jl7bUVx{zW)P7aNfMXMO7gwO;-nb049X(;_tLTW)EE!JIWNS^(Btwe<LqegCN5WB#h;@t$f&6ZSqOvOSG34o z^hsh0!CbspT}op9DA-a5K z7;}xklp{VR#QSRM@sM>g^AdNcR18dRvgD+#4XwPu8|hd{XX}|duM2*)_;_5Z8O8)3 zI1~7{SUeIk_3b{sAa~qzPah8fqW#2#kZ6h$qWTbS9Nc<@AAHDoQaIdVok%NWd?SiR z=|l-O2o$7zHS8YL=#x)%2y4kPbqEAQgm@px0k)LhIG0?~q{tMg5<)UK6hZ|}8Vk*; zop0u4vg47keT;Kj(uiD=P3J$Ed?JK4 zte3JbR+BIpc?i+>FfUehuZPU@$s`MAs&EYiYLRT0B(mu=J2q{XB=O04rx1dz@0XNU zc59GOPbk<{GetF;&VF9Be`PG1)Sj(|lyVmU%W|N3I%Ymj_+41N?)5Fg*4+KlbD-A_ za4+|$=Uij56a{Z^i{N_d58&pZiu$slaIxABb=cB0H%!a36t`aLz|{j8+A8*|VcXWS zkb{>>CKsuLq0s>)J|+b|`WK$Cn6*m6C&cJI5**?Xv}GfjY7nweL~xmyp8bNRzL0^y ztnJS7$&xd>h&I9?hc{8%<_ zDk!alp8n_hfuMA(0e?k=8FlgZs`lKz^(Md)YggFG9>QFWR>-_%*8oeU^x0nQVhj6` zKGX#hJ=-IzrNaPRuzMc4ldMS3wR#y4%N6EF`&HO>w$!YWRACAnvI122Z;}o}^5qUq z>){=xVnzfxXjOu!VsWp&42^^pHblRWZDGv{;>GeeZ5CnQis~IDB!?mVO}*6mh3C=% z9;H}^A>ysZrlW!f!S2U_oG{*;_m{KX51l0kp7FiILBg)1@@cs4Ne9Tle=HsN|HAb8 z&HoG23(niROi%s?)4_26gXvLQ>zM{fs0^RCR@8NTnUhN*egeZRK$l?WyHX2RK51(j zU;nkezN3pjP%FiIJ{^ST5Uc`mPVSHXb?Xzws|W>pRmuJyfxS|{OFTyVCV6VJCy@Ks z?z~7)ZoPmp4aAW5p5Mj?-#YCP=5O9CDn?H$p92iDPWDY#Es_m05Ac|K*M4s+jcuDn zXoCtjKgRc4HAg|n!Pz9P*Yrype^UZq|G)NDOUkd9wUYP8BOdwx3~t;1pTU**jn-)} z6&IffoYPl6*=^x=bmDsVY~mL=Hhp_uKxutd7Vv-JVjmp5UF@;oSkObcwr=-alI!pE zGny5kZJR;;eS)6Qh$4+^08R_7oU3{Z$+jj^k{T%2u?U&>+m{4t3wPtMQESnvL|jbJ z^?G1|=NJ9{c8J=HEvCp7-pc)2qveMF&f+gm;GJRPR#w-1w61o<2yUk=b5PWZo++HJ zvO+J!WU=K9e1CNfDw_JY-sAlfcOJo)J>0z*l^^v)sgDPk{PpieWb1d>;bKHS?0);n zKg7~uRLtrgBkDSfp*R&b`JwQXCJZ~y$0TjEOLsch)n@0b6{}#@8>$tPqgJO|lw#C7 zfb9Au(h`mOtNMl|TFbzt4LA{YilXgJ@!f&I?dJVnYXm*GD<&qnjPsh+ct_h285*pY zW*Omn*uTTFp?~20*2K5oR^BT`o}2Ive)i_wFh`0)TgJSL^2T5PGC^~Yoq*1 zI^K>ig9lQCc3XvZ!voj)wnld=@xZ=xfk=0?U)2o@X`m-aFr$i}k7!^vCNKJ&sUqqf_KaWuVR|A73moE3 z4K39CFa*>{i`p<6(hQCR+?k11AzEQmqTSdZDjLnGKDq6uVmJy07Vj^m(xj9F54eSOApVLSQM>iuF{ijv6Q3>4dTJuVF4o+rqrs!pCp`}w|g_*b6%Fd=gxt!q3I-L^3F{CK;_08(inE5 z6txm~LEJu*xOVA;y?#XvhHdGnj3%&Z8lL*N!b6Zjt#I&Q+040rMy-~O1M}`WlYG1QAgQi{4sU( z>`?d?59AhDQ{Xl?-bv+TD`O<*fw0gsBZvB~DF_hxjfG(u8L>G}WQ}aUxl_6(C)#HB zR&BoTs4`M<9ejxp7`wTvqV)|C#)W;xawk3Y?K=XHmB@riaE44b{yy4M>BfqJz$FMZ zU(yN3l2dM37eU08$+v=V;-fnBU$k`9R8Yr>O+q6zrv>p1TMnF113ic>BcT`%t^EJ^ zjN;$!eihTomfiHulwE=C=)(C=vStF(xESiraIyuj=fDELN3gfK_}=CUf4K#gvRA79 zWYlIBigUuo-!e6Z?Ca*U{%2{f$Rj_95HEj<3Uiqtj<`8$vP&MCe((FG#POY(T@|Zw zo9`rFkIExu-S21^hPS(BzdEUdc>i*6JpFSfYc-LGxUf5e==0^6Zz~xv#e+SyG@kxn zXiTVk1th}~BrH;9;~9Bs)degUt%4xgpmD>xpw%3)P4x#98v>vrN0eGrUhX5O`02sF@UdnSae0F}fPmU@$vRexjztPC zUlNrxNcu1hA{Z5f{_N35Z>Z*IN;@LEz(Y&}KU?mgr{)+@6~xnV2KM&?9R;4tB}Q}A zws$Z|F-Hh`S`a)9H=6r*a%1^#KJNKqz>a6}Zyl^S25aQlOaYJ+BN@;{LTiY=J`P1>|$d zMrv|R-Udf+4jDuZovMMN{8!P_(ExW*O(&)9aMK5|aqQc25MhJ%YKnu0BS3}2nfn4k@|9@>qIfA=iw#cswyRu=lvBNNk?NN-fgPbAh929>sFSq(Vk4%Cvy2ctHkqY# z%Q52uKYe@TQnPXE!}~yraq6H`CIa9Z#I0Q)2=ZLE$tko0GuQUtx&p9mMZ|nB2mFMf zqRc1mY(Z@NsgCh0IOTu#T}aYX`@*|HA6B}RdKChu$wnXM+Y~g?ScYkn>3oUih4=Rk zVq>3z)d%yADNc>i&K_C@ax66Xi%i_uInyx#^I)pd)rVU54WQ2%+p^mNP`Gk6ys2Z< zoTr`VHcU~ghu_L~Hed_A7^q40{KUu8|cNL{P(vT2sm1yPRxu z*4{qqiqv+N$EP`}Pvs#rvSEPm1DL0w@lb^TUirFML>ADm^N4I|oOKTpqKwRpNucx= z1LY?N-)^Q6x|%ZZ!)~X7pjptshe0?jLfWh4HnfHkFE`=0OC^zut$%F&Rjl>C9Cu%p z%?*5X77Vn4pX&L`yDEvjSt@dM#GBFp7iNI}O=SHneysmDv*>r^u{9nASt7cRF$Oep z&hysM{|TyKp;XF8)>c#*p4pLCw+OBScg7~%QqbClV@t5YoRv8X(rW5oIBwLmySSLK z@9~>c&zavOt};$9FY!*{?-I!HwM-4B{nbodZi8*l@Ndb1h*&9bF=1_5;-Z3o>}{v> z3tghaRv0`Z-}hzw1nIKk19!PRsMX|!cKY}ck`9|9$|X**_f#6Q6}3Y(=bT%l07asII*KeRYV(=Ti04kYl?F5f0`gV$lh z3n+*N7xP0)M$Q3cAS# zmzascsk?+ZT2r>+Kl^x4le68TW3(;Hdh4Gn3!4l@{76_&uc96gJAHa@u)vI<7o@Q<~4H z?Up{pkgLqY#fm_Z=-290sFCuuW)6$j6PEMjH>ku3nM5?Egx2nv;j|g%r2n(!Ac!->cly%RNB8Gf z&e_rdqZRf{0P9c?99yuPA|!ww`T|j9Q|qIBhK!_wzj{wn*uYJX;nptJ_ZMj4o(ZPG z!ZO@p49FFcte>Vvg2}II&8Wc^SRjTI%9cIPFJByI(`S0ErEN<{zM}y4SyBz`;b!aBR5|-_={h)g3FWMokw3X+d zi}f?O!fty=k3yWf|H4$V;C08{9fOoVsWU(V8W|KiW~G`?1#Qr3$_0!i#GWw*Rz;ZO z)kVozI8Q7WtJZU7H1sZdnpR6kBtW}sMQZyVsQYU1Rj^}k3e!=`z6G?1GI|%D-xCi* zzm!t40C%iBZkQFb>6#@}|_vxYQY2{klTTG$xe`6k)13c2FsWlE7RF4%|E; zOXgtZF|QoGss(~}tr|e{a4rH*qfY5l1+R>;qAI1#sLCM2NdzXRi#R05}%^Z(@?QuY7wX7=!SI@>1*squiggJ{oLv#`Fk+@?V|` zqWO22U@s0zwi^AlTxeFwr+9&bP}jW}z<&XmL^NYd2&|{5Qb(*fA6bTgLSsvhS>iaKf7~zrM z&#Jv4%}c;~L4Elz!|dyFxMu*)kbJGi)W^epuPFCW15`~`SCoG>Z}?`iCEK&17hmfH zQ_(V!~h=3&(8tNVn_MU^wz%tgJWW3Pt-Q5qYS7tkwX2$K=AX<5{-3(Q54 zbHP`-X`lXZkpB3WVuI^%klJ{SQ^+}Ir_1E+^JZ_4Lozu;&Y)uWflay4dfipKx?yc+ zJZgGoSuHC#d$5kR`_dFo@R^~8SfYNLoFTmff(@G<8sJT5|K7K^bY8O7@a!JduQ1d7 zuS*J0c>LQnc;nDr;#1?GGYOu*t;a^)EL*=nH%mFmrM%Fgws2O3TlO8hDI3sb{HjgH$tpBIHnm}XgsJ!qqhrRXo@?eVb$Xme!f6k zYNn_ruYLv?N^M$;$ZQfAtK2aEcWd1>7F@1v75wI*U)7hsPd|<*Pk=10pdLrbWJ)fm zk#T1Ur~=>-oDwb2PdXKDCYCqR1Dmu;5N=aM-b@U$)QC}Et!yZsBEgFwX5uZNH@%RO zP$ej5l~A9A`zvZauTeZRe9IYM;lHXDfwyN{hJ@%Ja8fRr zP{1!iLu>3BDgs22{azHI# z5K3+kCbzlV_u2IeL-01EIW+792Kq85U9bgw5>IxhY$Pf#ZP;Hae>aD8g@tWjJhRpZ zx`52Y4h^DLO(gDNg@iNg8A{T9xyzn!#*t~E>T5!Xnyq+0^ToNSqQ=1( z2a?v!6!r!}oDj^W#vrCTVdx<>+PP2meSk_QtBn7WB>EDcV|?v{>2fExNdLmfGE-^^W6_j+Qe3v}pgPhv?Ic_U=z^4$g~|3Bo-=QfNNscN z41E;yr(H9}uT~G^r%AQjtd*U-c>lFHo|Ns_;B7mbF2Go$dsZ8BZk zYR;N=MU-cc$=LRTIM6xyNr32?L0f6F#IBH3(HL&^?j8f3DLh_@+mg@;G?O($0yl9E z5=|yw;ib1Nw|eg{y?I*tXusn8#71Z=y;?AeJ;%;=JMn&8{)i$b?y8k3R{XHkY46eu5-JmuUdj!%bZJp4mb?6qpu)i@9-u>m+aq5^XwD4;j`afn4tmTWkc)6wXh+foT!0;xdD}}5IfmW4oDE>4aoxd z#nJ7?JIl4TWk9J6iow1U&)QmSvr8=8Y8pLh-I_+8Ine0J3RvLJaJ45CVw;RZ<}pr` z$4bRJBSf>zRP(c(XjIGjl5brw!ypKyn5BW?9(&6rziz${nIgtH&PXWVRnejZ(%%R; zQ510rj7o4i>OWjw!zWK1T#6f)_&)5gEhkTE_&%Bx@1PTtt%!v{e+4NJ<%YhOT0xLW z<9HV=fxZN(fZB1b)=h_0Z8r361piWrSx=i8bEZ|oPD>ZvXl@eE8T0OqZrw(mXzu@w zuOpH-S>6?3+p&{&VoJ&{4zf~vs5icN#l3Gvacf84nY~#3@z(fZ^;ouT`$g*T9GxZn zXHjyccOH30^mEH%@@@Ku^yHgOr&hRa=G{W#iZ76-s=;bZ)q(kzUu9F#VojK0!@*GK zW5(COLFwhC`KX~v4y>zFGj7$2 znw+2ZP>l6gkKBPMf?UZ>b_S!vwYrd?rpMKMAIHY+K=sRYd%Qh+vsnB3AL~>g=Qznt zfj_XYBTwYnd~`!Fo{W8J5pZi^BkUDwR4rmDfHLKM=mWedUD_`M`lNcq)@>zF{E+6e z(V9j!A6}B4T#I*IR-9y|P};(i3&T6T=mvE?u&72j-vg-KY ziK#GQZ9O;>0Hqc4B*3H$d>H?j7{&Z<^tNC0vQ#I#3K^E-M`}aw^^wR{PA<}sBTyM- zz$jRaYgu(ksK(Bi(!TlINO+kce!hJfU~u!^&V~QQdw+bI-{EEBnNX_xBHIv$X7cE+ z0dy4=se2%95TiCrBH~;whaMNi9TI3X8i*nuzX@tG7^e_{Y zZY`a}f)D6}$Oa^-+tfGLua(d59mV%|Qg_`;?(dD97xiqZ^%+aP9=dZsYV5H>4UycP zCZ6cu6<$Z(c>5DvqahAs9rjA)L_9=3d0p+NtG@l#$52^gTFROt;lEh90#4>Sj@f*`e# zh6rGG#%cPwZ7a@Dni}}67hGuoEywC!ITiuTP~gktGzh47j{jv)LZaa*L=0!!WJJOU z#r_yT>gdP%fS5P512J6o9q76BJv~uUmmcGIU+<;^B0(G8*L@NCpn+N(F*J17KUj<{ z)#$HkCOa9SViL?o&g?c802ggHybq6L(4<$Kt;>V4bH|6p;E#N_`}5|Rq2c?-)ydLL zfCB@{jZtr!3NhjH)FQMfmiHBbcbD_(KbQ2{BL;`w!=5AdZy)SYACUekEXcsC`{!>$ z1>Ewcv?MfynMC73vY?$lFc|!G$Fw%}^F+}a^mr6+hv!{~ZpkNpyRWVYp4J;5ADD+K z!P($Y@0aUcTS7~B&7$+SEvLgNhFFAXN<2}@lpZu0Qs>d+`E01H@E~u$Znb7&h2+T; zPF)7*i8ZJ`X$Wpq7@(j9J(HV(f-v*%uZN>8gKp22Z|4tFd*}D@nEnJ9xXro^DAY;B(RT~Bn}Rlu{Tyo2SL@51YUQ!4r`Eq;MO zpq(%Y$n2avWS&h&3ZjX)aDww=Q#L&7%KkyV`kew8n^F$nA}PpNchEU7ynve%?f9Pk z?Fig3XElE>1-jk(lWhWR-O8&dgF3-_F75&fcC4ObM8 z5GS;}Civp`@2tIWhOSk;+f21NZJxh>eI}BX*BLl0Ff(nA@HUZn0>)$^dQgr7&)Q(} z{oVC>38``z7f-tpG; ztST%^d}GwrO_M>V*?TNLiW-4ctz=Wujd%@@r_x4`Afa~|-s zZdiJ<)`xQg1)QG%lljG3L!h>7-#}Qafj{$Oh43;@&2Cw>4YDYTuJd{H<5`661t_cC zF~$P?Ox*o{+B)l?IGS(o6C`Mmh2ZY)?(VKxf&~o$f^1Ydk{4YIfdcXxMphv4pT zd7gWJ^}coMPF2tR(PyS+x_f5&bf531b83nzHRx`}O1>|PH^b!&ioF~ex%1>*7@ilD z4jg4c8XZyZS-q#n+E&uKX9hEd&1&e(nW`@e4n5-b!`$yI9zs5Z9cN0|37R#-fjtA! z{`Q$_76mI*$k}Rozbb#*61XIppH^dNy*th~)vgWJIG3~4_L3hw9ZQ=f0wGoh(}c>| zDtO8F+pF?6z?ogJy%-&Z#*p4zB{6tZod{{9PnnD|tQgE)tREL{dw8p|FY1xHYEcfR zV==sLjkV_ZJl|aowTa!k-xh<;FLr19qk4uF{X1F-7gRh<-7U?_r^JkIxhv1uPBgqK zzkP11DDC^Em0#7>1+g?#1!=hBzhC=ucOVlkMoYX|kuvx6R1F->yVmx&)7nXFdyez< z!6GfT*g!4Ok{A7UiQ}6l-c^u)9YOFTy-IVbIxGVr^bMT?sCY)l@mnon{&+ zup*+qu=gZ>H6p}L3|hqt1&<-eYhTVvR*%LufqF3o`ibHB?1t}Y<(PB>!`&Raf zu?DaFS!~5wAx#@oMK{jKB#m=_cXbo!2{m%R$OP}?mk*Y<3Z%L}?N$m{(^{$2At&mN z?(y+DwA#HhXe~W#^Xltu(-8_(LFlYoxw7aAC~duODEZNq*d)rR)-+HF@8hUkz zJ8cSYp!5rWJdi*&axx&(Whgs8j!kVQ-?ANq$2$f+tzMZs&JwR~qPFTOv5SbCmD>Ng zulWwYQ;Tu+_v7rCc999ZBocMtq0D;uI-rp#-mcq1I-ZBGKYa0*f-`%~5wAc(`P}&S zN>8W2!}CZ{a$2j$TfFS$zuKiTP+P<4*$jo!!NMHe%hp~_PL;|?uKoQB$oBe~(JYL!|!|NnzR5ld&@@wgL}_gq6W_XfYd+Za>s-rvmx3q1?1Wi`>K#?W!`tAkV9nx3?24re&dADQN53$jDQt52(}8Z zoRDnx@2bIR!v1LmOduh9tW|UjLiVqk)k7ia?2E3-WY&b>#Mh!f+FuS-O%xa8axE;=NKc)XR zyT`~^6vG@`MDL>jW-hbCq}?HhD*Tj9vXoX@0A;BJV0>9WJUcC5-EMT5N~_<0l>ji4 zR6sdl2$4}0Vw)Ncv~YIwt$cV$yyyv&`xtcsAC<%tlu$b(KnEuoCn9*NSV6ouL6opU}Sl<*T%}9G3Zn43;e{3g;C)Z z+-lbB&^cNVxmosmT#IALkDHK1L?X>6PvTsMowSpHP$!RWMkS} zpeOK-7Wh6zQ7ZdO}DGFjsmY>guFuqu}7Or%!ylZ!LiY;;BwZ z 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

Bq8H|anQgn3pqH!&iCAS+y``U=;{phnzm z&8`;H?Dw1;G5`tse6L5ey|?{ zBTQ0e0F@~|2a__No249Is%bc*T0J^=f&uB!g!-gj6RMbV ztWeFz)-pSA^YqWl?DOPI)FAGn#_ak#j@i|c>p!DWb zBVh6{Li6MFs)2Zue5qo;xf8;>9faY}7xEH*JN-D>PNs<>oD&VV&m!sVO5?xp;dxO{ z4C`r)I|?QI;m348CQpufYxY_0V(e-P@`Fq)2KB3(U_X8NUD^TBBmE}${xA#CNVqEb z_ctRQ*%*@je8q-X#LFBvKmLVvanO8|%|wO}oAUd|y<<%ml>P;38PZ$}$^8A}E7fi} zAt5Xea{vMC*fvk?V%AD{a{E`0Qi{UAT*|zO(|ne1`$@PwgR`nxlw3i11KaB9vR&+u zN|>(eABAND;n?AFHig~(eROpFp>B1-{ePTeCeI5=h>DLV>a4MeTXm-{L9e7D4|o5R zR?F+{+xI&9{`HSX7VvIm9e1^r*)3C)SAgxusTVfwjt8smUu9^DA|n^3C>Ay{Fm`-V z+G<&tbM2(Ez(X7T&{b%DKi+3+LeGStaHg!0>`?L9;Y~JpubnqL(=p%wErMDgKSrShocV^p2$@N~L}Crf2I!f`$TtPUH&g;+i(~@K!EDN7 zXRm>Iyr^WG7tnLi$$jvx8`_6kI!(p#K!$3uEl!4b_3?E$ontsuD6R3)Thn5y!e+Rn z7cpT~u!d1#&7yz+YDuM0o;IWHQ?!#_paaSC=h~ z4rr<;b>EG^tTrp>Lb!@o9ph%D=AbKEElnzZX z?Yv;rBpiRxASbf)7Y@}RZze2bYKat`fW|a|04Ns)^tQHAv*1(C((zpFvpaVP<}VWj zs^QVEA}ues_UcOSU}0eX&*je` teamHasFormatRecordList; + private static final long serialVersionUID = -6764484082819653225L; + @EmbeddedId + protected FormatPK formatPK; @JoinColumn(name = "game_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) @@ -85,25 +87,6 @@ public void setFormatPK(FormatPK formatPK) this.formatPK = formatPK; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDescription() - { - return description; - } - - public void setDescription(String description) - { - this.description = description; - } public Game getGame() { @@ -164,4 +147,35 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.Format[ formatPK=" + formatPK + " ]"; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + @XmlTransient + public List getTeamHasFormatRecordList() + { + return teamHasFormatRecordList; + } + + public void setTeamHasFormatRecordList(List teamHasFormatRecordList) + { + this.teamHasFormatRecordList = teamHasFormatRecordList; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java index 451340a..932be39 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Game.java @@ -35,6 +35,14 @@ }) public class Game implements Serializable { + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 45) + @Column(name = "name") + private String name; + @Size(max = 255) + @Column(name = "description") + private String description; private static final long serialVersionUID = -6267533299417173163L; @Id @Basic(optional = false) @@ -48,14 +56,6 @@ public class Game implements Serializable initialValue = 1) @Column(name = "id") private Integer id; - @Basic(optional = false) - @NotNull - @Size(min = 1, max = 45) - @Column(name = "name") - private String name; - @Size(max = 255) - @Column(name = "description") - private String description; @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") private List formatList; @OneToMany(cascade = CascadeType.ALL, mappedBy = "game") @@ -80,25 +80,6 @@ public void setId(Integer id) this.id = id; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDescription() - { - return description; - } - - public void setDescription(String description) - { - this.description = description; - } @XmlTransient public List getFormatList() @@ -148,4 +129,24 @@ public void setRecordList(List recordList) { this.recordList = recordList; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java index 093d7cc..cec1058 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java @@ -37,11 +37,8 @@ public class Team implements Serializable @Size(max = 245) @Column(name = "name") private String name; - // @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation - @Column(name = "mean") - private Double mean; - @Column(name = "sd") - private Double sd; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "team") + private List teamHasFormatRecordList; private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @@ -66,6 +63,7 @@ public Team() matchHasTeamList = new ArrayList<>(); playerList = new ArrayList<>(); tournamentHasTeamList = new ArrayList<>(); + teamHasFormatRecordList = new ArrayList<>(); } public Team(String name) @@ -84,7 +82,6 @@ public void setId(Integer id) this.id = id; } - @XmlTransient public List getPlayerList() { @@ -155,23 +152,14 @@ public void setName(String name) this.name = name; } - public Double getMean() - { - return mean; - } - - public void setMean(Double mean) - { - this.mean = mean; - } - - public Double getSd() + @XmlTransient + public List getTeamHasFormatRecordList() { - return sd; + return teamHasFormatRecordList; } - public void setSd(Double sd) + public void setTeamHasFormatRecordList(List teamHasFormatRecordList) { - this.sd = sd; + this.teamHasFormatRecordList = teamHasFormatRecordList; } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java new file mode 100644 index 0000000..81c6dcd --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java @@ -0,0 +1,164 @@ +package com.github.javydreamercsw.database.storage.db; + +import java.io.Serializable; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.JoinColumns; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import javax.xml.bind.annotation.XmlRootElement; + +@Entity +@Table(name = "team_has_format_record") +@XmlRootElement +@NamedQueries( +{ + @NamedQuery(name = "TeamHasFormatRecord.findAll", + query = "SELECT t FROM TeamHasFormatRecord t"), + @NamedQuery(name = "TeamHasFormatRecord.findByTeamId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.teamId = :teamId"), + @NamedQuery(name = "TeamHasFormatRecord.findByFormatId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatId = :formatId"), + @NamedQuery(name = "TeamHasFormatRecord.findByFormatGameId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatGameId = :formatGameId"), + @NamedQuery(name = "TeamHasFormatRecord.findByMean", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.mean = :mean"), + @NamedQuery(name = "TeamHasFormatRecord.findByStandardDeviation", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.standardDeviation = :standardDeviation") +}) +public class TeamHasFormatRecord implements Serializable +{ + private static final long serialVersionUID = 1L; + @EmbeddedId + protected TeamHasFormatRecordPK teamHasFormatRecordPK; + @Basic(optional = false) + @NotNull + @Column(name = "mean") + private double mean; + @Basic(optional = false) + @NotNull + @Column(name = "standard_deviation") + private double standardDeviation; + @JoinColumns( + { + @JoinColumn(name = "format_id", referencedColumnName = "id", + insertable = false, updatable = false), + @JoinColumn(name = "format_game_id", referencedColumnName = "game_id", + insertable = false, updatable = false) + }) + @ManyToOne(optional = false) + private Format format; + @JoinColumn(name = "team_id", referencedColumnName = "id", + insertable = false, updatable = false) + @ManyToOne(optional = false) + private Team team; + + public TeamHasFormatRecord() + { + } + + public TeamHasFormatRecord(TeamHasFormatRecordPK teamHasFormatRecordPK) + { + this.teamHasFormatRecordPK = teamHasFormatRecordPK; + } + + public TeamHasFormatRecord(TeamHasFormatRecordPK teamHasFormatRecordPK, + double mean, double standardDeviation) + { + this.teamHasFormatRecordPK = teamHasFormatRecordPK; + this.mean = mean; + this.standardDeviation = standardDeviation; + } + + public TeamHasFormatRecord(int teamId, int formatId, int formatGameId) + { + this.teamHasFormatRecordPK = new TeamHasFormatRecordPK(teamId, formatId, formatGameId); + } + + public TeamHasFormatRecordPK getTeamHasFormatRecordPK() + { + return teamHasFormatRecordPK; + } + + public void setTeamHasFormatRecordPK(TeamHasFormatRecordPK teamHasFormatRecordPK) + { + this.teamHasFormatRecordPK = teamHasFormatRecordPK; + } + + public double getMean() + { + return mean; + } + + public void setMean(double mean) + { + this.mean = mean; + } + + public double getStandardDeviation() + { + return standardDeviation; + } + + public void setStandardDeviation(double standardDeviation) + { + this.standardDeviation = standardDeviation; + } + + public Format getFormat() + { + return format; + } + + public void setFormat(Format format) + { + this.format = format; + } + + public Team getTeam() + { + return team; + } + + public void setTeam(Team team) + { + this.team = team; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (teamHasFormatRecordPK != null ? teamHasFormatRecordPK.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof TeamHasFormatRecord)) + { + return false; + } + TeamHasFormatRecord other = (TeamHasFormatRecord) object; + return !((this.teamHasFormatRecordPK == null + && other.teamHasFormatRecordPK != null) + || (this.teamHasFormatRecordPK != null + && !this.teamHasFormatRecordPK.equals(other.teamHasFormatRecordPK))); + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord[ teamHasFormatRecordPK=" + teamHasFormatRecordPK + " ]"; + } + +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecordPK.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecordPK.java new file mode 100644 index 0000000..31e38a9 --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecordPK.java @@ -0,0 +1,112 @@ +package com.github.javydreamercsw.database.storage.db; + +import java.io.Serializable; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.validation.constraints.NotNull; + +/** + * + * @author Javier Ortiz Bultron + */ +@Embeddable +public class TeamHasFormatRecordPK implements Serializable +{ + private static final long serialVersionUID = 11371362902792432L; + @Basic(optional = false) + @NotNull + @Column(name = "team_id") + private int teamId; + @Basic(optional = false) + @NotNull + @Column(name = "format_id") + private int formatId; + @Basic(optional = false) + @NotNull + @Column(name = "format_game_id") + private int formatGameId; + + public TeamHasFormatRecordPK() + { + } + + public TeamHasFormatRecordPK(int teamId, int formatId, int formatGameId) + { + this.teamId = teamId; + this.formatId = formatId; + this.formatGameId = formatGameId; + } + + public int getTeamId() + { + return teamId; + } + + public void setTeamId(int teamId) + { + this.teamId = teamId; + } + + public int getFormatId() + { + return formatId; + } + + public void setFormatId(int formatId) + { + this.formatId = formatId; + } + + public int getFormatGameId() + { + return formatGameId; + } + + public void setFormatGameId(int formatGameId) + { + this.formatGameId = formatGameId; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (int) teamId; + hash += (int) formatId; + hash += (int) formatGameId; + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof TeamHasFormatRecordPK)) + { + return false; + } + TeamHasFormatRecordPK other = (TeamHasFormatRecordPK) object; + if (this.teamId != other.teamId) + { + return false; + } + if (this.formatId != other.formatId) + { + return false; + } + if (this.formatGameId != other.formatGameId) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.TeamHasFormatRecordPK[ teamId=" + teamId + ", formatId=" + formatId + ", formatGameId=" + formatGameId + " ]"; + } + +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java index 0d918e7..12b8c56 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/FormatJpaController.java @@ -15,6 +15,7 @@ import com.github.javydreamercsw.database.storage.db.FormatPK; import com.github.javydreamercsw.database.storage.db.Game; import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; @@ -43,6 +44,10 @@ public void create(Format format) throws PreexistingEntityException, Exception { format.setTournamentList(new ArrayList<>()); } + if (format.getTeamHasFormatRecordList() == null) + { + format.setTeamHasFormatRecordList(new ArrayList<>()); + } format.getFormatPK().setGameId(format.getGame().getId()); EntityManager em = null; try @@ -69,6 +74,13 @@ public void create(Format format) throws PreexistingEntityException, Exception attachedTournamentList.add(tournamentListTournamentToAttach); } format.setTournamentList(attachedTournamentList); + List attachedTeamHasFormatRecordList = new ArrayList<>(); + for (TeamHasFormatRecord teamHasFormatRecordListTeamHasFormatRecordToAttach : format.getTeamHasFormatRecordList()) + { + teamHasFormatRecordListTeamHasFormatRecordToAttach = em.getReference(teamHasFormatRecordListTeamHasFormatRecordToAttach.getClass(), teamHasFormatRecordListTeamHasFormatRecordToAttach.getTeamHasFormatRecordPK()); + attachedTeamHasFormatRecordList.add(teamHasFormatRecordListTeamHasFormatRecordToAttach); + } + format.setTeamHasFormatRecordList(attachedTeamHasFormatRecordList); em.persist(format); if (game != null) { @@ -97,6 +109,17 @@ public void create(Format format) throws PreexistingEntityException, Exception oldFormatOfTournamentListTournament = em.merge(oldFormatOfTournamentListTournament); } } + for (TeamHasFormatRecord teamHasFormatRecordListTeamHasFormatRecord : format.getTeamHasFormatRecordList()) + { + Format oldFormatOfTeamHasFormatRecordListTeamHasFormatRecord = teamHasFormatRecordListTeamHasFormatRecord.getFormat(); + teamHasFormatRecordListTeamHasFormatRecord.setFormat(format); + teamHasFormatRecordListTeamHasFormatRecord = em.merge(teamHasFormatRecordListTeamHasFormatRecord); + if (oldFormatOfTeamHasFormatRecordListTeamHasFormatRecord != null) + { + oldFormatOfTeamHasFormatRecordListTeamHasFormatRecord.getTeamHasFormatRecordList().remove(teamHasFormatRecordListTeamHasFormatRecord); + oldFormatOfTeamHasFormatRecordListTeamHasFormatRecord = em.merge(oldFormatOfTeamHasFormatRecordListTeamHasFormatRecord); + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -131,6 +154,8 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity List matchEntryListNew = format.getMatchEntryList(); List tournamentListOld = persistentFormat.getTournamentList(); List tournamentListNew = format.getTournamentList(); + List teamHasFormatRecordListOld = persistentFormat.getTeamHasFormatRecordList(); + List teamHasFormatRecordListNew = format.getTeamHasFormatRecordList(); List illegalOrphanMessages = null; for (MatchEntry matchEntryListOldMatchEntry : matchEntryListOld) { @@ -154,6 +179,17 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity illegalOrphanMessages.add("You must retain Tournament " + tournamentListOldTournament + " since its format field is not nullable."); } } + for (TeamHasFormatRecord teamHasFormatRecordListOldTeamHasFormatRecord : teamHasFormatRecordListOld) + { + if (!teamHasFormatRecordListNew.contains(teamHasFormatRecordListOldTeamHasFormatRecord)) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("You must retain TeamHasFormatRecord " + teamHasFormatRecordListOldTeamHasFormatRecord + " since its format field is not nullable."); + } + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); @@ -179,6 +215,14 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity } tournamentListNew = attachedTournamentListNew; format.setTournamentList(tournamentListNew); + List attachedTeamHasFormatRecordListNew = new ArrayList<>(); + for (TeamHasFormatRecord teamHasFormatRecordListNewTeamHasFormatRecordToAttach : teamHasFormatRecordListNew) + { + teamHasFormatRecordListNewTeamHasFormatRecordToAttach = em.getReference(teamHasFormatRecordListNewTeamHasFormatRecordToAttach.getClass(), teamHasFormatRecordListNewTeamHasFormatRecordToAttach.getTeamHasFormatRecordPK()); + attachedTeamHasFormatRecordListNew.add(teamHasFormatRecordListNewTeamHasFormatRecordToAttach); + } + teamHasFormatRecordListNew = attachedTeamHasFormatRecordListNew; + format.setTeamHasFormatRecordList(teamHasFormatRecordListNew); format = em.merge(format); if (gameOld != null && !gameOld.equals(gameNew)) { @@ -218,6 +262,20 @@ public void edit(Format format) throws IllegalOrphanException, NonexistentEntity } } } + for (TeamHasFormatRecord teamHasFormatRecordListNewTeamHasFormatRecord : teamHasFormatRecordListNew) + { + if (!teamHasFormatRecordListOld.contains(teamHasFormatRecordListNewTeamHasFormatRecord)) + { + Format oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord = teamHasFormatRecordListNewTeamHasFormatRecord.getFormat(); + teamHasFormatRecordListNewTeamHasFormatRecord.setFormat(format); + teamHasFormatRecordListNewTeamHasFormatRecord = em.merge(teamHasFormatRecordListNewTeamHasFormatRecord); + if (oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord != null && !oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord.equals(format)) + { + oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord.getTeamHasFormatRecordList().remove(teamHasFormatRecordListNewTeamHasFormatRecord); + oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord = em.merge(oldFormatOfTeamHasFormatRecordListNewTeamHasFormatRecord); + } + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -278,6 +336,15 @@ public void destroy(FormatPK id) throws IllegalOrphanException, NonexistentEntit } illegalOrphanMessages.add("This Format (" + format + ") cannot be destroyed since the Tournament " + tournamentListOrphanCheckTournament + " in its tournamentList field has a non-nullable format field."); } + List teamHasFormatRecordListOrphanCheck = format.getTeamHasFormatRecordList(); + for (TeamHasFormatRecord teamHasFormatRecordListOrphanCheckTeamHasFormatRecord : teamHasFormatRecordListOrphanCheck) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("This Format (" + format + ") cannot be destroyed since the TeamHasFormatRecord " + teamHasFormatRecordListOrphanCheckTeamHasFormatRecord + " in its teamHasFormatRecordList field has a non-nullable format field."); + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamHasFormatRecordJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamHasFormatRecordJpaController.java new file mode 100644 index 0000000..910eb2a --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamHasFormatRecordJpaController.java @@ -0,0 +1,257 @@ +package com.github.javydreamercsw.database.storage.db.controller; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityNotFoundException; +import javax.persistence.Query; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +import com.github.javydreamercsw.database.storage.db.Format; +import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecordPK; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.database.storage.db.controller.exceptions.PreexistingEntityException; +import com.github.javydreamercsw.database.storage.db.server.AbstractController; + +public class TeamHasFormatRecordJpaController extends AbstractController implements Serializable +{ + private static final long serialVersionUID = 2465839189233391174L; + public TeamHasFormatRecordJpaController(EntityManagerFactory emf) + { + super(emf); + } + + public void create(TeamHasFormatRecord teamHasFormatRecord) throws PreexistingEntityException, Exception + { + if (teamHasFormatRecord.getTeamHasFormatRecordPK() == null) + { + teamHasFormatRecord.setTeamHasFormatRecordPK(new TeamHasFormatRecordPK()); + } + teamHasFormatRecord.getTeamHasFormatRecordPK().setFormatGameId(teamHasFormatRecord.getFormat().getFormatPK().getGameId()); + teamHasFormatRecord.getTeamHasFormatRecordPK().setFormatId(teamHasFormatRecord.getFormat().getFormatPK().getId()); + teamHasFormatRecord.getTeamHasFormatRecordPK().setTeamId(teamHasFormatRecord.getTeam().getId()); + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + Format format = teamHasFormatRecord.getFormat(); + if (format != null) + { + format = em.getReference(format.getClass(), format.getFormatPK()); + teamHasFormatRecord.setFormat(format); + } + Team team = teamHasFormatRecord.getTeam(); + if (team != null) + { + team = em.getReference(team.getClass(), team.getId()); + teamHasFormatRecord.setTeam(team); + } + em.persist(teamHasFormatRecord); + if (format != null) + { + format.getTeamHasFormatRecordList().add(teamHasFormatRecord); + format = em.merge(format); + } + if (team != null) + { + team.getTeamHasFormatRecordList().add(teamHasFormatRecord); + team = em.merge(team); + } + em.getTransaction().commit(); + } + catch (Exception ex) + { + if (findTeamHasFormatRecord(teamHasFormatRecord.getTeamHasFormatRecordPK()) != null) + { + throw new PreexistingEntityException("TeamHasFormatRecord " + teamHasFormatRecord + " already exists.", ex); + } + throw ex; + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public void edit(TeamHasFormatRecord teamHasFormatRecord) throws NonexistentEntityException, Exception + { + teamHasFormatRecord.getTeamHasFormatRecordPK().setFormatGameId(teamHasFormatRecord.getFormat().getFormatPK().getGameId()); + teamHasFormatRecord.getTeamHasFormatRecordPK().setFormatId(teamHasFormatRecord.getFormat().getFormatPK().getId()); + teamHasFormatRecord.getTeamHasFormatRecordPK().setTeamId(teamHasFormatRecord.getTeam().getId()); + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + TeamHasFormatRecord persistentTeamHasFormatRecord = em.find(TeamHasFormatRecord.class, teamHasFormatRecord.getTeamHasFormatRecordPK()); + Format formatOld = persistentTeamHasFormatRecord.getFormat(); + Format formatNew = teamHasFormatRecord.getFormat(); + Team teamOld = persistentTeamHasFormatRecord.getTeam(); + Team teamNew = teamHasFormatRecord.getTeam(); + if (formatNew != null) + { + formatNew = em.getReference(formatNew.getClass(), formatNew.getFormatPK()); + teamHasFormatRecord.setFormat(formatNew); + } + if (teamNew != null) + { + teamNew = em.getReference(teamNew.getClass(), teamNew.getId()); + teamHasFormatRecord.setTeam(teamNew); + } + teamHasFormatRecord = em.merge(teamHasFormatRecord); + if (formatOld != null && !formatOld.equals(formatNew)) + { + formatOld.getTeamHasFormatRecordList().remove(teamHasFormatRecord); + formatOld = em.merge(formatOld); + } + if (formatNew != null && !formatNew.equals(formatOld)) + { + formatNew.getTeamHasFormatRecordList().add(teamHasFormatRecord); + formatNew = em.merge(formatNew); + } + if (teamOld != null && !teamOld.equals(teamNew)) + { + teamOld.getTeamHasFormatRecordList().remove(teamHasFormatRecord); + teamOld = em.merge(teamOld); + } + if (teamNew != null && !teamNew.equals(teamOld)) + { + teamNew.getTeamHasFormatRecordList().add(teamHasFormatRecord); + teamNew = em.merge(teamNew); + } + em.getTransaction().commit(); + } + catch (Exception ex) + { + String msg = ex.getLocalizedMessage(); + if (msg == null || msg.length() == 0) + { + TeamHasFormatRecordPK id = teamHasFormatRecord.getTeamHasFormatRecordPK(); + if (findTeamHasFormatRecord(id) == null) + { + throw new NonexistentEntityException("The teamHasFormatRecord with id " + id + " no longer exists."); + } + } + throw ex; + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public void destroy(TeamHasFormatRecordPK id) throws NonexistentEntityException + { + EntityManager em = null; + try + { + em = getEntityManager(); + em.getTransaction().begin(); + TeamHasFormatRecord teamHasFormatRecord; + try + { + teamHasFormatRecord = em.getReference(TeamHasFormatRecord.class, id); + teamHasFormatRecord.getTeamHasFormatRecordPK(); + } + catch (EntityNotFoundException enfe) + { + throw new NonexistentEntityException("The teamHasFormatRecord with id " + id + " no longer exists.", enfe); + } + Format format = teamHasFormatRecord.getFormat(); + if (format != null) + { + format.getTeamHasFormatRecordList().remove(teamHasFormatRecord); + format = em.merge(format); + } + Team team = teamHasFormatRecord.getTeam(); + if (team != null) + { + team.getTeamHasFormatRecordList().remove(teamHasFormatRecord); + team = em.merge(team); + } + em.remove(teamHasFormatRecord); + em.getTransaction().commit(); + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + public List findTeamHasFormatRecordEntities() + { + return findTeamHasFormatRecordEntities(true, -1, -1); + } + + public List findTeamHasFormatRecordEntities(int maxResults, int firstResult) + { + return findTeamHasFormatRecordEntities(false, maxResults, firstResult); + } + + private List findTeamHasFormatRecordEntities(boolean all, int maxResults, int firstResult) + { + EntityManager em = getEntityManager(); + try + { + CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); + cq.select(cq.from(TeamHasFormatRecord.class)); + Query q = em.createQuery(cq); + if (!all) + { + q.setMaxResults(maxResults); + q.setFirstResult(firstResult); + } + return q.getResultList(); + } + finally + { + em.close(); + } + } + + public TeamHasFormatRecord findTeamHasFormatRecord(TeamHasFormatRecordPK id) + { + EntityManager em = getEntityManager(); + try + { + return em.find(TeamHasFormatRecord.class, id); + } + finally + { + em.close(); + } + } + + public int getTeamHasFormatRecordCount() + { + EntityManager em = getEntityManager(); + try + { + CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); + Root rt = cq.from(TeamHasFormatRecord.class); + cq.select(em.getCriteriaBuilder().count(rt)); + Query q = em.createQuery(cq); + return ((Long) q.getSingleResult()).intValue(); + } + finally + { + em.close(); + } + } + +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamJpaController.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamJpaController.java index 7a3805b..8b54a5d 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamJpaController.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/controller/TeamJpaController.java @@ -14,6 +14,7 @@ import com.github.javydreamercsw.database.storage.db.MatchHasTeam; import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; import com.github.javydreamercsw.database.storage.db.TournamentHasTeam; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; @@ -42,6 +43,10 @@ public void create(Team team) { team.setTournamentHasTeamList(new ArrayList<>()); } + if (team.getTeamHasFormatRecordList() == null) + { + team.setTeamHasFormatRecordList(new ArrayList<>()); + } EntityManager em = null; try { @@ -68,6 +73,13 @@ public void create(Team team) attachedTournamentHasTeamList.add(tournamentHasTeamListTournamentHasTeamToAttach); } team.setTournamentHasTeamList(attachedTournamentHasTeamList); + List attachedTeamHasFormatRecordList = new ArrayList<>(); + for (TeamHasFormatRecord teamHasFormatRecordListTeamHasFormatRecordToAttach : team.getTeamHasFormatRecordList()) + { + teamHasFormatRecordListTeamHasFormatRecordToAttach = em.getReference(teamHasFormatRecordListTeamHasFormatRecordToAttach.getClass(), teamHasFormatRecordListTeamHasFormatRecordToAttach.getTeamHasFormatRecordPK()); + attachedTeamHasFormatRecordList.add(teamHasFormatRecordListTeamHasFormatRecordToAttach); + } + team.setTeamHasFormatRecordList(attachedTeamHasFormatRecordList); em.persist(team); for (Player playerListPlayer : team.getPlayerList()) { @@ -96,6 +108,17 @@ public void create(Team team) oldTeamOfTournamentHasTeamListTournamentHasTeam = em.merge(oldTeamOfTournamentHasTeamListTournamentHasTeam); } } + for (TeamHasFormatRecord teamHasFormatRecordListTeamHasFormatRecord : team.getTeamHasFormatRecordList()) + { + Team oldTeamOfTeamHasFormatRecordListTeamHasFormatRecord = teamHasFormatRecordListTeamHasFormatRecord.getTeam(); + teamHasFormatRecordListTeamHasFormatRecord.setTeam(team); + teamHasFormatRecordListTeamHasFormatRecord = em.merge(teamHasFormatRecordListTeamHasFormatRecord); + if (oldTeamOfTeamHasFormatRecordListTeamHasFormatRecord != null) + { + oldTeamOfTeamHasFormatRecordListTeamHasFormatRecord.getTeamHasFormatRecordList().remove(teamHasFormatRecordListTeamHasFormatRecord); + oldTeamOfTeamHasFormatRecordListTeamHasFormatRecord = em.merge(oldTeamOfTeamHasFormatRecordListTeamHasFormatRecord); + } + } em.getTransaction().commit(); } finally @@ -121,6 +144,8 @@ public void edit(Team team) throws IllegalOrphanException, NonexistentEntityExce List matchHasTeamListNew = team.getMatchHasTeamList(); List tournamentHasTeamListOld = persistentTeam.getTournamentHasTeamList(); List tournamentHasTeamListNew = team.getTournamentHasTeamList(); + List teamHasFormatRecordListOld = persistentTeam.getTeamHasFormatRecordList(); + List teamHasFormatRecordListNew = team.getTeamHasFormatRecordList(); List illegalOrphanMessages = null; for (MatchHasTeam matchHasTeamListOldMatchHasTeam : matchHasTeamListOld) { @@ -144,6 +169,17 @@ public void edit(Team team) throws IllegalOrphanException, NonexistentEntityExce illegalOrphanMessages.add("You must retain TournamentHasTeam " + tournamentHasTeamListOldTournamentHasTeam + " since its team field is not nullable."); } } + for (TeamHasFormatRecord teamHasFormatRecordListOldTeamHasFormatRecord : teamHasFormatRecordListOld) + { + if (!teamHasFormatRecordListNew.contains(teamHasFormatRecordListOldTeamHasFormatRecord)) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("You must retain TeamHasFormatRecord " + teamHasFormatRecordListOldTeamHasFormatRecord + " since its team field is not nullable."); + } + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); @@ -172,6 +208,14 @@ public void edit(Team team) throws IllegalOrphanException, NonexistentEntityExce } tournamentHasTeamListNew = attachedTournamentHasTeamListNew; team.setTournamentHasTeamList(tournamentHasTeamListNew); + List attachedTeamHasFormatRecordListNew = new ArrayList<>(); + for (TeamHasFormatRecord teamHasFormatRecordListNewTeamHasFormatRecordToAttach : teamHasFormatRecordListNew) + { + teamHasFormatRecordListNewTeamHasFormatRecordToAttach = em.getReference(teamHasFormatRecordListNewTeamHasFormatRecordToAttach.getClass(), teamHasFormatRecordListNewTeamHasFormatRecordToAttach.getTeamHasFormatRecordPK()); + attachedTeamHasFormatRecordListNew.add(teamHasFormatRecordListNewTeamHasFormatRecordToAttach); + } + teamHasFormatRecordListNew = attachedTeamHasFormatRecordListNew; + team.setTeamHasFormatRecordList(teamHasFormatRecordListNew); team = em.merge(team); for (Player playerListOldPlayer : playerListOld) { @@ -217,6 +261,20 @@ public void edit(Team team) throws IllegalOrphanException, NonexistentEntityExce } } } + for (TeamHasFormatRecord teamHasFormatRecordListNewTeamHasFormatRecord : teamHasFormatRecordListNew) + { + if (!teamHasFormatRecordListOld.contains(teamHasFormatRecordListNewTeamHasFormatRecord)) + { + Team oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord = teamHasFormatRecordListNewTeamHasFormatRecord.getTeam(); + teamHasFormatRecordListNewTeamHasFormatRecord.setTeam(team); + teamHasFormatRecordListNewTeamHasFormatRecord = em.merge(teamHasFormatRecordListNewTeamHasFormatRecord); + if (oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord != null && !oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord.equals(team)) + { + oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord.getTeamHasFormatRecordList().remove(teamHasFormatRecordListNewTeamHasFormatRecord); + oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord = em.merge(oldTeamOfTeamHasFormatRecordListNewTeamHasFormatRecord); + } + } + } em.getTransaction().commit(); } catch (Exception ex) @@ -277,6 +335,15 @@ public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntity } illegalOrphanMessages.add("This Team (" + team + ") cannot be destroyed since the TournamentHasTeam " + tournamentHasTeamListOrphanCheckTournamentHasTeam + " in its tournamentHasTeamList field has a non-nullable team field."); } + List teamHasFormatRecordListOrphanCheck = team.getTeamHasFormatRecordList(); + for (TeamHasFormatRecord teamHasFormatRecordListOrphanCheckTeamHasFormatRecord : teamHasFormatRecordListOrphanCheck) + { + if (illegalOrphanMessages == null) + { + illegalOrphanMessages = new ArrayList<>(); + } + illegalOrphanMessages.add("This Team (" + team + ") cannot be destroyed since the TeamHasFormatRecord " + teamHasFormatRecordListOrphanCheckTeamHasFormatRecord + " in its teamHasFormatRecordList field has a non-nullable team field."); + } if (illegalOrphanMessages != null) { throw new IllegalOrphanException(illegalOrphanMessages); @@ -359,5 +426,5 @@ public int getTeamCount() em.close(); } } - + } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index 78b88b4..074763c 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -5,6 +5,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -524,6 +525,7 @@ public static void loadDemoData() throws Exception t.setWinPoints(3); t.setLossPoints(0); t.setDrawPoints(1); + t.setStartDate(LocalDateTime.now().minusDays(startDay)); t.setFormat(FormatService.getInstance().getAll().get(0)); t.setTournamentFormat(TournamentService.getInstance() @@ -559,18 +561,11 @@ public static void loadDemoData() throws Exception ? "result.loss" : "result.win").get()); MatchService.getInstance().setRanked(match, ranked); - //Lock the results so records are updated. - match.getMatchHasTeamList().forEach(mht -> - { - try - { - MatchService.getInstance().lockMatchResult(mht.getMatchResult()); - } - catch (Exception ex) - { - Exceptions.printStackTrace(ex); - } - }); + // Lock the results so records are updated. + MatchService.getInstance().lockMatchResult(match); + + // Update rankings + MatchService.getInstance().updateRankings(match); } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/FormatService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/FormatService.java index 052662b..a6de069 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/FormatService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/FormatService.java @@ -197,7 +197,11 @@ public void deleteFormat(Format format) { fc.destroy(format.getFormatPK()); } - catch (NonexistentEntityException | IllegalOrphanException ex) + catch (IllegalOrphanException ex) + { + Exceptions.printStackTrace(ex); + } + catch (NonexistentEntityException ex) { Exceptions.printStackTrace(ex); } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index 9da593a..6b9834e 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -1,11 +1,15 @@ package com.github.javydreamercsw.database.storage.db.server; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import org.openide.util.Exceptions; +import org.openide.util.Lookup; import com.github.javydreamercsw.database.storage.db.MatchEntry; import com.github.javydreamercsw.database.storage.db.MatchEntryPK; @@ -13,15 +17,26 @@ import com.github.javydreamercsw.database.storage.db.MatchHasTeamPK; import com.github.javydreamercsw.database.storage.db.MatchResult; import com.github.javydreamercsw.database.storage.db.MatchResultType; +import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Record; import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecordPK; import com.github.javydreamercsw.database.storage.db.controller.MatchEntryJpaController; import com.github.javydreamercsw.database.storage.db.controller.MatchHasTeamJpaController; import com.github.javydreamercsw.database.storage.db.controller.MatchResultJpaController; import com.github.javydreamercsw.database.storage.db.controller.MatchResultTypeJpaController; +import com.github.javydreamercsw.database.storage.db.controller.TeamHasFormatRecordJpaController; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import com.github.javydreamercsw.tournament.manager.UIPlayer; +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; import com.github.javydreamercsw.tournament.manager.api.TournamentException; +import com.github.javydreamercsw.tournament.manager.api.standing.RankingProvider; +import com.github.javydreamercsw.trueskill.TrueSkillRankingProvider; + +import de.gesundkrank.jskills.IPlayer; +import de.gesundkrank.jskills.Rating; public class MatchService extends Service { @@ -33,6 +48,10 @@ public class MatchService extends Service = new MatchResultJpaController(DataBaseManager.getEntityManagerFactory()); private MatchResultTypeJpaController mrtc = new MatchResultTypeJpaController(DataBaseManager.getEntityManagerFactory()); + private final RankingProvider rp + = Lookup.getDefault().lookup(RankingProvider.class); + private final TeamHasFormatRecordJpaController thfrc + = new TeamHasFormatRecordJpaController(DataBaseManager.getEntityManagerFactory()); /** * Helper class to initialize the singleton Service in a thread-safe way and @@ -294,6 +313,35 @@ public void setResult(MatchHasTeam mht, MatchResultType mrt) mht.setMatchResult(mr); } + /** + * Lock the match result.This is meant not to be undone as it calculates + * experience and update records which is dependent on when it happens. + * + * @param me Match Result to lock. + * @throws TournamentException + */ + public void lockMatchResult(MatchEntry me) throws TournamentException + { + for (MatchHasTeam mht : findMatch(me.getMatchEntryPK()).getMatchHasTeamList()) + { + if (mht != null) + { + try + { + lockMatchResult(mht.getMatchResult()); + } + catch (Exception ex) + { + throw new TournamentException(ex); + } + } + else + { + throw new TournamentException("Missing result!"); + } + } + } + /** * Lock the match result.This is meant not to be undone as it calculates * experience and update records which is dependent on when it happens. @@ -383,4 +431,141 @@ public void setRanked(MatchEntry match, boolean ranked) } } } + + /** + * Update rankings for the match. This assumes that all losers were eliminated + * at the same time. + * + * @param me Match entry to check. + * @throws TournamentException + */ + public void updateRankings(final MatchEntry me) throws TournamentException + { + updateRankings(me, new HashMap<>()); + } + + /** + * Update rankings for the match. This allows to give extra credits for losing + * teams that lasted longer in the match. Use 1 for the key of the winner, 2 + * for the runner up and so on. Value implemented as a list to handle ties on + * each place. + * + * @param me Match entry to check. + * @param order Map indicating the place as key and a list of team id's as + * value. + * @throws TournamentException + */ + public void updateRankings(final MatchEntry me, + Map> order) throws TournamentException + { + TrueSkillRankingProvider p = (TrueSkillRankingProvider) rp; + // First make sure that everyone has a result + MatchEntry match = findMatch(me.getMatchEntryPK()); + for (MatchHasTeam mht : match.getMatchHasTeamList()) + { + if (mht.getMatchResult() == null || !mht.getMatchResult().getLocked()) + { + throw new TournamentException("Not all teams have a locked result!"); + } + } + + TeamInterface[] teams = new TeamInterface[match.getMatchHasTeamList().size()]; + int[] resultOrder = new int[match.getMatchHasTeamList().size()]; + //Ok, now check the order if any + if (order.isEmpty()) + { + order.put(1, new ArrayList<>()); + order.put(2, new ArrayList<>()); + // Create an order with the winner as first place and everyone else tied for second. + for (MatchHasTeam mht : match.getMatchHasTeamList()) + { + switch (mht.getMatchResult().getMatchResultType().getType()) + { + case "result.win": + order.get(1).add(mht.getTeam().getId()); + break; + default: + order.get(2).add(mht.getTeam().getId()); + } + } + } + + //Convert into the JSkill interface for calculations + for (MatchHasTeam mht : match.getMatchHasTeamList()) + { + try + { + p.addTeam(TeamService.getInstance().convertToTeam(mht.getTeam(), + me.getFormat())); + } + catch (Exception ex) + { + throw new TournamentException(ex); + } + } + + int count = 0; + for (Entry> entry : order.entrySet()) + { + for (Integer t : entry.getValue()) + { + teams[count] = TeamService.getInstance() + .convertToTeam(TeamService.getInstance().findTeam(t), + me.getFormat()); + resultOrder[count++] = entry.getKey(); + } + } + + // Make the calculations + Map ratings + = p.getCalculator().calculateNewRatings(p.getGameInfo(), + de.gesundkrank.jskills.Team.concat(teams), + resultOrder); + + // Now persist to database + for (Entry entry : ratings.entrySet()) + { + Optional temp + = PlayerService.getInstance() + .findPlayerById(((UIPlayer) entry.getKey()).getID()); + if (temp.isPresent()) + { + Player player = temp.get(); + + //This assumes that the first tema is the team only contaiining the player. + Team team = player.getTeamList().get(0); + try + { + if (TeamService.getInstance().hasFormatRecord(team, me.getFormat())) + { + //Update it + TeamHasFormatRecord thfr + = TeamService.getInstance().getFormatRecord(team, me.getFormat()); + thfr.setMean(entry.getValue().getMean()); + thfr.setStandardDeviation(entry.getValue().getStandardDeviation()); + thfrc.edit(thfr); + } + else + { + TeamHasFormatRecord thfr + = new TeamHasFormatRecord(new TeamHasFormatRecordPK( + team.getId(), + me.getFormat().getFormatPK().getId(), + me.getFormat().getFormatPK().getGameId()), + entry.getValue().getMean(), + entry.getValue().getStandardDeviation()); + thfr.setFormat(me.getFormat()); + thfr.setTeam(team); + thfrc.create(thfr); + team.getTeamHasFormatRecordList().add(thfr); + } + } + catch (Exception ex) + { + throw new TournamentException(ex); + } + TeamService.getInstance().saveTeam(team); + } + } + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java index 639f3bb..54ed4c8 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/PlayerService.java @@ -205,9 +205,19 @@ public void savePlayer(Player player) throws Exception } } - @Override + @Override public List getAll() { return pc.findPlayerEntities(); } + + /** + * Convert a player to a UIPlayer. + * @param p Player to transform + * @return transformed player. + */ + public UIPlayer convertToUIPlayer(Player p) + { + return new UIPlayer(p.getName(), p.getId()); + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java index fad11ce..54ffc64 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TeamService.java @@ -5,21 +5,28 @@ import org.openide.util.Exceptions; +import com.github.javydreamercsw.database.storage.db.Format; import com.github.javydreamercsw.database.storage.db.MatchHasTeam; import com.github.javydreamercsw.database.storage.db.Player; import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; import com.github.javydreamercsw.database.storage.db.TournamentHasTeam; import com.github.javydreamercsw.database.storage.db.controller.MatchHasTeamJpaController; +import com.github.javydreamercsw.database.storage.db.controller.TeamHasFormatRecordJpaController; import com.github.javydreamercsw.database.storage.db.controller.TeamJpaController; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; +import de.gesundkrank.jskills.Rating; + public class TeamService extends Service { private TeamJpaController tc = new TeamJpaController(DataBaseManager.getEntityManagerFactory()); private MatchHasTeamJpaController mhtc = new MatchHasTeamJpaController(DataBaseManager.getEntityManagerFactory()); + private final TeamHasFormatRecordJpaController thfrc + = new TeamHasFormatRecordJpaController(DataBaseManager.getEntityManagerFactory()); private TeamService() { @@ -120,6 +127,10 @@ public void deleteTeam(Team t) { TournamentService.getInstance().deleteTeamFromTournament(tht); } + for (TeamHasFormatRecord thfr : t.getTeamHasFormatRecordList()) + { + thfrc.destroy(thfr.getTeamHasFormatRecordPK()); + } tc.destroy(t.getId()); } catch (IllegalOrphanException | NonexistentEntityException ex) @@ -172,4 +183,67 @@ public List getAll() { return tc.findTeamEntities(); } + + /** + * Convert a team form the database representation to the JSKill + * representation. + * + * @param t Team to convert. + * @param format Format to get ratings for. + * @return converted team. + */ + public com.github.javydreamercsw.tournament.manager.Team convertToTeam(Team t, + Format format) + { + com.github.javydreamercsw.tournament.manager.Team team + = new com.github.javydreamercsw.tournament.manager.Team(t.getId(), + new ArrayList<>()); + t.getPlayerList().forEach(player -> + { + Rating r; + if (hasFormatRecord(t, format)) + { + TeamHasFormatRecord thfr = getFormatRecord(t, format); + r = new Rating(thfr.getMean(), thfr.getStandardDeviation()); + } + else + { + r = new Rating(0.0, 0.0); + } + team.addPlayer(PlayerService.getInstance().convertToUIPlayer(player), r); + }); + return team; + } + + /** + * Check if this team has a record entry in the database for this format. + * + * @param team Team to check. + * @param format Format to check + * @return true if exists, false otherwise. + */ + public boolean hasFormatRecord(Team team, Format format) + { + return getFormatRecord(team, format) != null; + } + + /** + * Get the teams record for the specified format. + * + * @param team Team to check. + * @param format Format to check. + * @return Record or null if not found. + */ + public TeamHasFormatRecord getFormatRecord(Team team, Format format) + { + for (TeamHasFormatRecord thfr + : findTeam(team.getId()).getTeamHasFormatRecordList()) + { + if (thfr.getFormat().getFormatPK().equals(format.getFormatPK())) + { + return thfr; + } + } + return null; + } } diff --git a/Database-Storage/src/main/resources/META-INF/persistence.xml b/Database-Storage/src/main/resources/META-INF/persistence.xml index b6d5218..ce02ed0 100644 --- a/Database-Storage/src/main/resources/META-INF/persistence.xml +++ b/Database-Storage/src/main/resources/META-INF/persistence.xml @@ -12,6 +12,7 @@ com.github.javydreamercsw.database.storage.db.Record com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team + com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord com.github.javydreamercsw.database.storage.db.Tournament com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam @@ -39,6 +40,7 @@ com.github.javydreamercsw.database.storage.db.Record com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team + com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord com.github.javydreamercsw.database.storage.db.Tournament com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam @@ -67,6 +69,7 @@ com.github.javydreamercsw.database.storage.db.Record com.github.javydreamercsw.database.storage.db.Round com.github.javydreamercsw.database.storage.db.Team + com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord com.github.javydreamercsw.database.storage.db.Tournament com.github.javydreamercsw.database.storage.db.TournamentFormat com.github.javydreamercsw.database.storage.db.TournamentHasTeam diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java index a598604..cfe3bc3 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManagerTest.java @@ -14,6 +14,7 @@ import com.github.javydreamercsw.database.storage.db.AbstractServerTest; import com.github.javydreamercsw.database.storage.db.MatchEntry; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; import com.github.javydreamercsw.tournament.manager.api.IGame; public class DataBaseManagerTest extends AbstractServerTest @@ -33,6 +34,7 @@ public void testLoadDemoData() throws Exception assertFalse(PlayerService.getInstance().getAll().isEmpty()); assertFalse(TournamentService.getInstance().getAll().isEmpty()); assertFalse(TournamentService.getInstance().getAllFormats().isEmpty()); + assertFalse(FormatService.getInstance().getAll().isEmpty()); assertFalse(MatchService.getInstance().getAll().isEmpty()); assertFalse(TeamService.getInstance().getAll().isEmpty()); assertFalse(RecordService.getInstance().getAll().isEmpty()); @@ -52,6 +54,24 @@ public void testLoadDemoData() throws Exception assertEquals(m.getMatchHasTeamList().size(), 2); assertNotNull(m.getFormat()); }); + + results = DataBaseManager.namedQuery("TeamHasFormatRecord.findAll"); + assertTrue(results.size() > 0); + + results.forEach(result -> + { + TeamHasFormatRecord m = (TeamHasFormatRecord) result; + assertNotNull(m.getTeam()); + assertNotNull(m.getFormat()); + }); + + FormatService.getInstance().getAll().forEach(format -> + { + if (format.getMatchEntryList().size() > 0) + { + assertTrue(format.getTeamHasFormatRecordList().size() > 0); + } + }); } @Test @@ -59,7 +79,7 @@ public void testNamedQuery() { Map parameters = new HashMap<>(); parameters.put("name", Lookup.getDefault().lookup(IGame.class).getName()); - + assertFalse(DataBaseManager.namedQuery("Game.findByName", parameters).isEmpty()); } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index 14821d9..9523647 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -17,6 +17,8 @@ import com.github.javydreamercsw.database.storage.db.MatchResult; import com.github.javydreamercsw.database.storage.db.MatchResultType; import com.github.javydreamercsw.database.storage.db.Player; +import com.github.javydreamercsw.database.storage.db.Team; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; import com.github.javydreamercsw.database.storage.db.Tournament; import com.github.javydreamercsw.database.storage.db.controller.exceptions.IllegalOrphanException; import com.github.javydreamercsw.database.storage.db.controller.exceptions.NonexistentEntityException; @@ -170,13 +172,19 @@ public void testMatchService() throws TournamentException, Exception MatchService.getInstance().saveMatch(me); - for (MatchHasTeam mht : me.getMatchHasTeamList()) + MatchService.getInstance().lockMatchResult(me); + + MatchService.getInstance().updateRankings(me); + + //Check the stats + me.getMatchHasTeamList().forEach(mht -> { - MatchResult mr = mht.getMatchResult(); - assertNotNull(mr); - mr.setLocked(true); - MatchService.getInstance().updateResult(mr); - } + Team dbTeam = TeamService.getInstance().findTeam(mht.getTeam().getId()); + TeamHasFormatRecord thfr = + TeamService.getInstance().getFormatRecord(dbTeam, me.getFormat()); + assertNotNull(thfr); + assertTrue(thfr.getMean() + thfr.getStandardDeviation() != 0); + }); TeamService.getInstance().getAll().forEach(team -> { diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/UIPlayer.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/UIPlayer.java index ce95223..48ff145 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/UIPlayer.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/UIPlayer.java @@ -8,7 +8,6 @@ import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; import com.github.javydreamercsw.tournament.manager.api.Variables; - import com.github.javydreamercsw.tournament.manager.api.standing.RecordInterface; /** @@ -66,7 +65,7 @@ public String getName() @Override public int getID() { - return getId(); + return id; } @Override @@ -99,14 +98,6 @@ public TournamentPlayerInterface createInstance(String name, int id) return createInstance(name, id, 0, 0, 0); } - /** - * @return the id - */ - public int getId() - { - return id; - } - @Override public void setName(String name) { diff --git a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/standing/RankingProvider.java b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/standing/RankingProvider.java index ab61f15..cf8e7ea 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/standing/RankingProvider.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/tournament/manager/api/standing/RankingProvider.java @@ -9,11 +9,10 @@ public interface RankingProvider { /** - * Add a match into the rankings. + * Add teams into the rankings. * - * @param title Match title. * @param teams Teams participating on the match. * @throws java.lang.Exception */ - void addMatch(String title, TeamInterface... teams) throws Exception; + void addTeam(TeamInterface... teams) throws Exception; } diff --git a/TMCore/src/main/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProvider.java b/TMCore/src/main/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProvider.java index a9a76de..773c303 100644 --- a/TMCore/src/main/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProvider.java +++ b/TMCore/src/main/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProvider.java @@ -8,6 +8,10 @@ import org.openide.util.lookup.ServiceProvider; +import com.github.javydreamercsw.tournament.manager.api.TeamInterface; +import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; +import com.github.javydreamercsw.tournament.manager.api.standing.RankingProvider; + import de.gesundkrank.jskills.GameInfo; import de.gesundkrank.jskills.Player; import de.gesundkrank.jskills.SkillCalculator; @@ -16,11 +20,6 @@ import de.gesundkrank.jskills.trueskill.TwoPlayerTrueSkillCalculator; import de.gesundkrank.jskills.trueskill.TwoTeamTrueSkillCalculator; -import com.github.javydreamercsw.tournament.manager.api.TeamInterface; -import com.github.javydreamercsw.tournament.manager.api.TournamentPlayerInterface; - -import com.github.javydreamercsw.tournament.manager.api.standing.RankingProvider; - /** * * @author Javier A. Ortiz Bultron @@ -33,7 +32,7 @@ public class TrueSkillRankingProvider implements RankingProvider private SkillCalculator calculator; @Override - public void addMatch(String title, TeamInterface... teams) throws Exception + public void addTeam(TeamInterface... teams) throws Exception { for (TeamInterface team : teams) { diff --git a/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java b/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java index d22ef22..3d5144b 100644 --- a/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java +++ b/TMCore/src/test/java/com/github/javydreamercsw/trueskill/TrueSkillRankingProviderNGTest.java @@ -37,7 +37,7 @@ public TrueSkillRankingProviderNGTest() } /** - * Test of addMatch method, of class TrueSkillRankingProvider. + * Test of addTeam method, of class TrueSkillRankingProvider. * * @throws java.lang.Exception */ @@ -52,7 +52,7 @@ public void testMatch() throws Exception { new Team(1, p1), new Team(2, p2) }; - instance.addMatch("Test Match", teams); + instance.addTeam(teams); TrueSkillRankingProvider p = (TrueSkillRankingProvider) instance; List teamList = p.getTeamList(); assertEquals(teamList.size(), playerCount); @@ -82,7 +82,7 @@ public void testMatch() throws Exception new Team(3, p3), new Team(4, p4) }; - instance.addMatch("Test Match 2", teams); + instance.addTeam(teams); teamList = p.getTeamList(); @@ -110,7 +110,7 @@ public void testMatch() throws Exception new Team(1, p1), new Team(2, p2), new Team(3, p3), new Team(4, p4) }; - instance.addMatch("Test Match 3", teams); + instance.addTeam(teams); teamList = p.getTeamList(); diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/MainLayout.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/MainLayout.java index 52ed6ea..bf3e2e3 100755 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/MainLayout.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/MainLayout.java @@ -27,6 +27,7 @@ import com.github.javydreamercsw.tournament.manager.ui.views.formatlist.FormatList; import com.github.javydreamercsw.tournament.manager.ui.views.matchlist.MatchList; import com.github.javydreamercsw.tournament.manager.ui.views.playerlist.PlayerList; +import com.github.javydreamercsw.tournament.manager.ui.views.rankings.RankingList; import com.github.javydreamercsw.tournament.manager.ui.views.tournamentlist.TournamentList; import com.github.javydreamercsw.tournament.manager.ui.views.welcome.Welcome; import com.vaadin.flow.component.Component; @@ -82,10 +83,15 @@ public MainLayout() throws NamingException RouterLink players = new RouterLink(null, PlayerList.class); players.add(new Icon(VaadinIcon.USERS), new Text("Players")); players.addClassName("main-layout__nav-item"); + + RouterLink rankings = new RouterLink(null, RankingList.class); + rankings.add(new Icon(VaadinIcon.TABLE), new Text("Rankings")); + rankings.addClassName("main-layout__nav-item"); List components = new ArrayList<>(); components.add(welcome); components.add(players); + components.add(rankings); if (demo) { diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java new file mode 100644 index 0000000..c38e226 --- /dev/null +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java @@ -0,0 +1,92 @@ +package com.github.javydreamercsw.tournament.manager.ui.views.rankings; + +import static com.github.javydreamercsw.tournament.manager.ui.views.TMView.CURRENT_GAME; + +import java.util.List; + +import com.github.javydreamercsw.database.storage.db.Format; +import com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord; +import com.github.javydreamercsw.database.storage.db.server.FormatService; +import com.github.javydreamercsw.tournament.manager.ui.MainLayout; +import com.github.javydreamercsw.tournament.manager.ui.common.FormatLabelGenerator; +import com.github.javydreamercsw.tournament.manager.ui.views.TMView; +import com.vaadin.flow.component.combobox.ComboBox; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.grid.Grid.SelectionMode; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.data.provider.ListDataProvider; +import com.vaadin.flow.router.PageTitle; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.server.VaadinService; + +/** + * Displays the list of rankings. + */ +@Route(value = "rankings", layout = MainLayout.class) +@PageTitle("Rankings") +public class RankingList extends TMView +{ + private static final long serialVersionUID = 495427102994660040L; + private final ComboBox format = new ComboBox<>("Format"); + private final Grid rankings = new Grid<>(); + private int index=0; + + public RankingList() + { + VerticalLayout container = new VerticalLayout(); + // Add the top menu + HorizontalLayout header = new HorizontalLayout(); + + // Add the format selector + List formats = FormatService.getInstance().findFormatByGame( + (String) VaadinService.getCurrentRequest().getWrappedSession() + .getAttribute(CURRENT_GAME)); + + format.setDataProvider(new ListDataProvider<>(formats)); + format.setItemLabelGenerator(new FormatLabelGenerator()); + format.setRequired(true); + format.setPreventInvalidInput(true); + format.setAllowCustomValue(false); + format.addValueChangeListener(event -> updateView()); + format.setValue(formats.get(0)); + + header.add(format); + + rankings.addColumn(this::getRowIndex).setWidth("8em") + .setResizable(true); + rankings.addColumn(this::getTeam).setHeader("Team").setWidth("8em") + .setResizable(true); + rankings.addColumn(TeamHasFormatRecord::getMean).setHeader("Mean") + .setWidth("6em"); + rankings.addColumn(TeamHasFormatRecord::getStandardDeviation) + .setHeader("Standard Deviation") + .setWidth("6em"); + rankings.setSelectionMode(SelectionMode.NONE); + + container.add(header, rankings); + add(container); + } + + private String getRowIndex(TeamHasFormatRecord thfr){ + index++; + return String.valueOf(index); + } + + private String getTeam(TeamHasFormatRecord thfr) + { + return thfr.getTeam().getName(); + } + + @Override + public void updateView() + { + //Update rankings based on format + Format f = format.getValue(); + if (f != null) + { + // Get all the rankings for this format. + rankings.setItems(f.getTeamHasFormatRecordList()); + } + } +} From 2dd2796e24ecf3f3cc2e3fc609d30704245dc523 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Fri, 28 Dec 2018 21:36:52 -0600 Subject: [PATCH 24/25] Add ranking points --- Database-Storage/DB.mwb | Bin 31629 -> 31758 bytes Database-Storage/DB.mwb.bak | Bin 31664 -> 31629 bytes .../database/storage/db/Format.java | 23 +-- .../database/storage/db/Team.java | 19 ++- .../storage/db/TeamHasFormatRecord.java | 114 +++++++------ .../storage/db/server/MatchService.java | 160 +++++++++++++++++- .../storage/db/server/MatchServiceTest.java | 146 +++++++++++++--- .../ui/views/rankings/RankingList.java | 14 +- 8 files changed, 371 insertions(+), 105 deletions(-) diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index 2f912df88f1fc108a861daffb4797524005c13c6..bcde4d19df8f3dd420bfb598f5fc533e9c5d6fdf 100644 GIT binary patch delta 30234 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 delta 12293 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 diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java index 63d536a..2595741 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Format.java @@ -148,6 +148,18 @@ public String toString() + formatPK + " ]"; } + + @XmlTransient + public List getTeamHasFormatRecordList() + { + return teamHasFormatRecordList; + } + + public void setTeamHasFormatRecordList(List teamHasFormatRecordList) + { + this.teamHasFormatRecordList = teamHasFormatRecordList; + } + public String getName() { return name; @@ -167,15 +179,4 @@ public void setDescription(String description) { this.description = description; } - - @XmlTransient - public List getTeamHasFormatRecordList() - { - return teamHasFormatRecordList; - } - - public void setTeamHasFormatRecordList(List teamHasFormatRecordList) - { - this.teamHasFormatRecordList = teamHasFormatRecordList; - } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java index cec1058..75fa1f7 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Team.java @@ -142,15 +142,6 @@ public String toString() return "com.github.javydreamercsw.database.storage.db.Team[ id=" + id + " ]"; } - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } @XmlTransient public List getTeamHasFormatRecordList() @@ -162,4 +153,14 @@ public void setTeamHasFormatRecordList(List teamHasFormatRe { this.teamHasFormatRecordList = teamHasFormatRecordList; } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java index 81c6dcd..ac9dd03 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TeamHasFormatRecord.java @@ -19,25 +19,23 @@ @Table(name = "team_has_format_record") @XmlRootElement @NamedQueries( -{ - @NamedQuery(name = "TeamHasFormatRecord.findAll", - query = "SELECT t FROM TeamHasFormatRecord t"), - @NamedQuery(name = "TeamHasFormatRecord.findByTeamId", - query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.teamId = :teamId"), - @NamedQuery(name = "TeamHasFormatRecord.findByFormatId", - query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatId = :formatId"), - @NamedQuery(name = "TeamHasFormatRecord.findByFormatGameId", - query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatGameId = :formatGameId"), - @NamedQuery(name = "TeamHasFormatRecord.findByMean", - query = "SELECT t FROM TeamHasFormatRecord t WHERE t.mean = :mean"), - @NamedQuery(name = "TeamHasFormatRecord.findByStandardDeviation", - query = "SELECT t FROM TeamHasFormatRecord t WHERE t.standardDeviation = :standardDeviation") -}) + { + @NamedQuery(name = "TeamHasFormatRecord.findAll", + query = "SELECT t FROM TeamHasFormatRecord t"), + @NamedQuery(name = "TeamHasFormatRecord.findByTeamId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.teamId = :teamId"), + @NamedQuery(name = "TeamHasFormatRecord.findByFormatId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatId = :formatId"), + @NamedQuery(name = "TeamHasFormatRecord.findByFormatGameId", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.teamHasFormatRecordPK.formatGameId = :formatGameId"), + @NamedQuery(name = "TeamHasFormatRecord.findByMean", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.mean = :mean"), + @NamedQuery(name = "TeamHasFormatRecord.findByStandardDeviation", + query = "SELECT t FROM TeamHasFormatRecord t WHERE t.standardDeviation = :standardDeviation") + }) public class TeamHasFormatRecord implements Serializable { - private static final long serialVersionUID = 1L; - @EmbeddedId - protected TeamHasFormatRecordPK teamHasFormatRecordPK; + private static final long serialVersionUID = 1517758449111184848L; @Basic(optional = false) @NotNull @Column(name = "mean") @@ -46,16 +44,22 @@ public class TeamHasFormatRecord implements Serializable @NotNull @Column(name = "standard_deviation") private double standardDeviation; + @Basic(optional = false) + @NotNull + @Column(name = "points") + private int points; + @EmbeddedId + protected TeamHasFormatRecordPK teamHasFormatRecordPK; @JoinColumns( - { - @JoinColumn(name = "format_id", referencedColumnName = "id", - insertable = false, updatable = false), - @JoinColumn(name = "format_game_id", referencedColumnName = "game_id", - insertable = false, updatable = false) - }) + { + @JoinColumn(name = "format_id", referencedColumnName = "id", + insertable = false, updatable = false), + @JoinColumn(name = "format_game_id", referencedColumnName = "game_id", + insertable = false, updatable = false) + }) @ManyToOne(optional = false) private Format format; - @JoinColumn(name = "team_id", referencedColumnName = "id", + @JoinColumn(name = "team_id", referencedColumnName = "id", insertable = false, updatable = false) @ManyToOne(optional = false) private Team team; @@ -69,7 +73,7 @@ public TeamHasFormatRecord(TeamHasFormatRecordPK teamHasFormatRecordPK) this.teamHasFormatRecordPK = teamHasFormatRecordPK; } - public TeamHasFormatRecord(TeamHasFormatRecordPK teamHasFormatRecordPK, + public TeamHasFormatRecord(TeamHasFormatRecordPK teamHasFormatRecordPK, double mean, double standardDeviation) { this.teamHasFormatRecordPK = teamHasFormatRecordPK; @@ -92,26 +96,6 @@ public void setTeamHasFormatRecordPK(TeamHasFormatRecordPK teamHasFormatRecordPK this.teamHasFormatRecordPK = teamHasFormatRecordPK; } - public double getMean() - { - return mean; - } - - public void setMean(double mean) - { - this.mean = mean; - } - - public double getStandardDeviation() - { - return standardDeviation; - } - - public void setStandardDeviation(double standardDeviation) - { - this.standardDeviation = standardDeviation; - } - public Format getFormat() { return format; @@ -149,16 +133,46 @@ public boolean equals(Object object) return false; } TeamHasFormatRecord other = (TeamHasFormatRecord) object; - return !((this.teamHasFormatRecordPK == null - && other.teamHasFormatRecordPK != null) - || (this.teamHasFormatRecordPK != null + return !((this.teamHasFormatRecordPK == null + && other.teamHasFormatRecordPK != null) + || (this.teamHasFormatRecordPK != null && !this.teamHasFormatRecordPK.equals(other.teamHasFormatRecordPK))); } @Override public String toString() { - return "com.github.javydreamercsw.database.storage.db.TeamHasFormatRecord[ teamHasFormatRecordPK=" + teamHasFormatRecordPK + " ]"; + return "Points: " + getPoints() + "\nMean: " + getMean() + "\nSD: " + + getStandardDeviation(); + } + + public double getMean() + { + return mean; + } + + public void setMean(double mean) + { + this.mean = mean; + } + + public double getStandardDeviation() + { + return standardDeviation; + } + + public void setStandardDeviation(double standardDeviation) + { + this.standardDeviation = standardDeviation; + } + + public int getPoints() + { + return points; + } + + public void setPoints(int points) + { + this.points = points; } - } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java index 6b9834e..6e37224 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/MatchService.java @@ -516,6 +516,16 @@ public void updateRankings(final MatchEntry me, } } + /** + * Quality of the match is used to determine how even the match up is. It'll + * be a number between 0% and 100%. + * + * The closest to zero the higher reward for the lower ranked for a win and + * the lower reward for the higher ranked for the win. This number takes + * into account all the skills from all the teams in the match. + */ + double quality = getMatchQuality(teams); + // Make the calculations Map ratings = p.getCalculator().calculateNewRatings(p.getGameInfo(), @@ -532,8 +542,12 @@ public void updateRankings(final MatchEntry me, { Player player = temp.get(); - //This assumes that the first tema is the team only contaiining the player. + // This assumes that the first tema is the team only contaiining the player. Team team = player.getTeamList().get(0); + + int totalPoints = (int) getMatchPointsEarned(team, me, quality); + + // Change modifier based on who beated who try { if (TeamService.getInstance().hasFormatRecord(team, me.getFormat())) @@ -543,6 +557,12 @@ public void updateRankings(final MatchEntry me, = TeamService.getInstance().getFormatRecord(team, me.getFormat()); thfr.setMean(entry.getValue().getMean()); thfr.setStandardDeviation(entry.getValue().getStandardDeviation()); + thfr.setPoints(thfr.getPoints() + totalPoints); + if (thfr.getPoints() < 0) + { + // Don't go below zero. + thfr.setPoints(0); + } thfrc.edit(thfr); } else @@ -556,6 +576,8 @@ public void updateRankings(final MatchEntry me, entry.getValue().getStandardDeviation()); thfr.setFormat(me.getFormat()); thfr.setTeam(team); + //If it'll go below zero ignore it. + thfr.setPoints(totalPoints > 0 ? totalPoints : 0); thfrc.create(thfr); team.getTeamHasFormatRecordList().add(thfr); } @@ -568,4 +590,140 @@ public void updateRankings(final MatchEntry me, } } } + + /** + * Calculate the point modifier based on the match quality. + * + * @param quality Match quality + * @return modifier. + */ + protected double calculateModifier(double quality) + { + double modifier; + if (quality >= 90) + { + modifier = 1.0; + } + else if (quality >= 80) + { + modifier = 1.1; + } + else if (quality >= 70) + { + modifier = 1.2; + } + else if (quality >= 60) + { + modifier = 1.3; + } + else if (quality >= 50) + { + modifier = 1.4; + } + else if (quality >= 40) + { + modifier = 1.5; + } + else if (quality >= 30) + { + modifier = 1.6; + } + else if (quality >= 20) + { + modifier = 1.7; + } + else if (quality >= 10) + { + modifier = 1.8; + } + else + { + modifier = 2.0; + } + return modifier; + } + + /** + * Calculate match points to add/remove based on the result of the match. + * + * @param team Team to calculate points for. + * @param me Match to calculate points for. + * @param quality Match quality + * @return points earned/lost. + */ + protected double getMatchPointsEarned(Team team, MatchEntry me, double quality) + { + double base = 10.0; + + // Find result to adjust base accordingly + for (MatchHasTeam mht : findMatch(me.getMatchEntryPK()).getMatchHasTeamList()) + { + if (Objects.equals(mht.getTeam().getId(), team.getId())) + { + switch (mht.getMatchResult().getMatchResultType().getType()) + { + case "result.loss": + // Fall thru + case "result.forfeit": + // Fall thru + case "result.no_show": + // Points are substracted in a loss. + base *= -1; + break; + case "result.draw": + base = 0.0; + break; + default: + // No modification + break; + } + break; + } + } + + return base * calculateModifier(quality); + } + + /** + * Get math quality. + * + * @param me Match entry. + * @return Quality of the match, in percentage. + * @throws TournamentException if there's an error converting teams. + */ + public double getMatchQuality(MatchEntry me) throws TournamentException + { + TeamInterface[] teams = new TeamInterface[me.getMatchHasTeamList().size()]; + //Convert into the JSkill interface for calculations + + int count = 0; + for (MatchHasTeam mht : me.getMatchHasTeamList()) + { + try + { + teams[count] = TeamService.getInstance().convertToTeam(mht.getTeam(), + me.getFormat()); + count++; + } + catch (Exception ex) + { + throw new TournamentException(ex); + } + } + + return getMatchQuality(teams); + } + + /** + * Get math quality. + * + * @param teams Teams to get quality from. + * @return Quality of the match, in percentage. + */ + public double getMatchQuality(TeamInterface[] teams) + { + return ((TrueSkillRankingProvider) rp).getCalculator().calculateMatchQuality( + ((TrueSkillRankingProvider) rp).getGameInfo(), + de.gesundkrank.jskills.Team.concat(teams)) * 100; + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java index 9523647..7d74b93 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/MatchServiceTest.java @@ -3,11 +3,14 @@ import static org.testng.Assert.*; import java.util.List; +import java.util.Optional; import java.util.Random; import org.openide.util.Exceptions; import org.openide.util.Lookup; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.github.javydreamercsw.database.storage.db.AbstractServerTest; @@ -34,6 +37,7 @@ public class MatchServiceTest extends AbstractServerTest { private Game game; private MatchEntry me; + private Tournament t = new Tournament("Test 1"); @BeforeClass @Override @@ -43,7 +47,6 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, super.setup(); game = GameService.getInstance().findGameByName(Lookup.getDefault() .lookup(IGame.class).getName()).get(); - Tournament t = new Tournament("Test 1"); t.setTournamentFormat(TournamentService.getInstance() .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) .getName())); @@ -60,6 +63,26 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, MatchService.getInstance().saveMatch(me); } + @AfterMethod + public void reset() + { + TeamService.getInstance().getAll().forEach(team -> + { + try + { + MatchService.getInstance().removeTeam(me, team); + } + catch (NonexistentEntityException ex) + { + Exceptions.printStackTrace(ex); + fail(); + } + }); + + assertTrue(MatchService.getInstance().findMatch(me.getMatchEntryPK()) + .getMatchHasTeamList().isEmpty()); + } + /** * Test of write2DB method, of class MatchServer. * @@ -69,14 +92,6 @@ public void setup() throws NonexistentEntityException, IllegalOrphanException, @Test public void testMatchService() throws TournamentException, Exception { - Tournament t = new Tournament("Test 1"); - t.setTournamentFormat(TournamentService.getInstance() - .findFormat(Lookup.getDefault().lookup(TournamentInterface.class) - .getName())); - t.setFormat(FormatService.getInstance().getAll().get(0)); - TournamentService.getInstance().saveTournament(t); - TournamentService.getInstance().addRound(t); - MatchEntry match = MatchService.getInstance().findMatch(me.getMatchEntryPK()); assertNotNull(me.getFormat()); @@ -180,40 +195,119 @@ public void testMatchService() throws TournamentException, Exception me.getMatchHasTeamList().forEach(mht -> { Team dbTeam = TeamService.getInstance().findTeam(mht.getTeam().getId()); - TeamHasFormatRecord thfr = - TeamService.getInstance().getFormatRecord(dbTeam, me.getFormat()); + TeamHasFormatRecord thfr + = TeamService.getInstance().getFormatRecord(dbTeam, me.getFormat()); assertNotNull(thfr); assertTrue(thfr.getMean() + thfr.getStandardDeviation() != 0); }); + } + + @Test + public void testFindMatchesWithFormat() + { + assertEquals(MatchService.getInstance().findMatchesWithFormat("").size(), + game.getFormatList().size()); + + assertEquals(MatchService.getInstance() + .findMatchesWithFormat(game.getFormatList().get(0).getName()).size(), 1); + + assertTrue(MatchService.getInstance() + .findMatchesWithFormat(game.getFormatList().get(0).getName() + "x") + .isEmpty()); + } + + @DataProvider + public Object[][] getQualityToTest() + { + Object[][] data = new Object[10][]; + for (int i = 10; i >0; i--) + { + data[10-i] = new Object[] + { + i * 10.0 + }; + } + return data; + } + + @Test(dataProvider = "getQualityToTest") + public void testcalculateBasePoints(double quality) throws Exception + { + // Add teams + Optional p1 = PlayerService.getInstance().findPlayerByName("Player 1"); + Optional p2 = PlayerService.getInstance().findPlayerByName("Player 2"); + Player player = p1.isPresent() ? p1.get() : new Player("Player 1"); + PlayerService.getInstance().savePlayer(player); + + Player player2 = p2.isPresent() ? p2.get() : new Player("Player 2"); + PlayerService.getInstance().savePlayer(player2); TeamService.getInstance().getAll().forEach(team -> { try { - MatchService.getInstance().removeTeam(me, team); + MatchService.getInstance().addTeam(me, team); } - catch (NonexistentEntityException ex) + catch (Exception ex) { Exceptions.printStackTrace(ex); fail(); } }); - assertTrue(MatchService.getInstance().findMatch(me.getMatchEntryPK()) - .getMatchHasTeamList().isEmpty()); - } + double calculatedQuality; + do + { + int count = 0; + for (MatchHasTeam mht : me.getMatchHasTeamList()) + { + MatchService.getInstance().setResult(mht, + count == 0 ? MatchService.getInstance().getResultType("result.win").get() + : MatchService.getInstance().getResultType("result.loss").get()); + count++; + } + TeamHasFormatRecord thfr1 = TeamService.getInstance().getFormatRecord( + MatchService.getInstance().findMatch(me.getMatchEntryPK()) + .getMatchHasTeamList().get(0).getTeam(), + game.getFormatList().get(0)); - @Test - public void testFindMatchesWithFormat() - { - assertEquals(MatchService.getInstance().findMatchesWithFormat("").size(), - game.getFormatList().size()); + double player1Points = thfr1 == null ? 0.0 : thfr1.getPoints(); - assertEquals(MatchService.getInstance() - .findMatchesWithFormat(game.getFormatList().get(0).getName()).size(), 1); + MatchService.getInstance().lockMatchResult(me); + MatchService.getInstance().updateRankings(me); - assertTrue(MatchService.getInstance() - .findMatchesWithFormat(game.getFormatList().get(0).getName() + "x") - .isEmpty()); + // Check results + MatchService.getInstance().findMatch(me.getMatchEntryPK()) + .getMatchHasTeamList().forEach((mht) -> + { + if (mht.getMatchResult().getMatchResultType().getType().equals("result.win")) + { + assertEquals(TeamService.getInstance().getFormatRecord(mht.getTeam(), + game.getFormatList().get(0)).getPoints() - player1Points, + 10.0 * MatchService.getInstance().calculateModifier(quality)); + } + else + { + assertEquals(TeamService.getInstance().getFormatRecord(mht.getTeam(), + game.getFormatList().get(0)).getPoints(), 0); + } + }); + + calculatedQuality = MatchService.getInstance().getMatchQuality(me); + } + while (calculatedQuality > quality); + + TeamService.getInstance().getAll().forEach(team -> + { + try + { + MatchService.getInstance().removeTeam(me, team); + } + catch (NonexistentEntityException ex) + { + Exceptions.printStackTrace(ex); + fail(); + } + }); } } diff --git a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java index c38e226..9a4d0d6 100644 --- a/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java +++ b/TournamentManagerWeb/src/main/java/com/github/javydreamercsw/tournament/manager/ui/views/rankings/RankingList.java @@ -30,7 +30,7 @@ public class RankingList extends TMView private static final long serialVersionUID = 495427102994660040L; private final ComboBox format = new ComboBox<>("Format"); private final Grid rankings = new Grid<>(); - private int index=0; + private int index = 0; public RankingList() { @@ -53,22 +53,20 @@ public RankingList() header.add(format); - rankings.addColumn(this::getRowIndex).setWidth("8em") + rankings.addColumn(this::getRowIndex).setWidth("2em") .setResizable(true); rankings.addColumn(this::getTeam).setHeader("Team").setWidth("8em") .setResizable(true); - rankings.addColumn(TeamHasFormatRecord::getMean).setHeader("Mean") - .setWidth("6em"); - rankings.addColumn(TeamHasFormatRecord::getStandardDeviation) - .setHeader("Standard Deviation") + rankings.addColumn(TeamHasFormatRecord::getPoints).setHeader("Points") .setWidth("6em"); rankings.setSelectionMode(SelectionMode.NONE); container.add(header, rankings); add(container); } - - private String getRowIndex(TeamHasFormatRecord thfr){ + + private String getRowIndex(TeamHasFormatRecord thfr) + { index++; return String.valueOf(index); } From 51fba711d71d9885ca3bd743d787ee47130cc299 Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Fri, 28 Dec 2018 21:52:43 -0600 Subject: [PATCH 25/25] Add JaCoCo coverage --- pom.xml | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index e62164e..d584fca 100644 --- a/pom.xml +++ b/pom.xml @@ -37,13 +37,18 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.1 + ${surefire.version} org.apache.maven.plugins maven-failsafe-plugin - 2.22.1 + ${surefire.version} + + org.apache.maven.plugins + maven-surefire-report-plugin + ${surefire.version} + @@ -138,18 +143,39 @@ + - org.jacoco - jacoco-maven-plugin + org.apache.maven.plugins + maven-project-info-reports-plugin + 3.0.0 + + false + - - report - + summary + index + dependencies + team + licenses + scm + mailing-lists + issue-management + modules + - + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + org.jacoco + jacoco-maven-plugin + @@ -165,6 +191,7 @@ UTF-8 RELEASE802 6.14.3 + 2.22.1

nrug8DwhbzDjP@ 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 KJ3{bWg#RB{?^KKc diff --git a/Database-Storage/pom.xml b/Database-Storage/pom.xml index 4c6dede..89b722a 100644 --- a/Database-Storage/pom.xml +++ b/Database-Storage/pom.xml @@ -57,5 +57,11 @@ 2.3.1 jar + + org.hamcrest + hamcrest-all + 1.3 + test + diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java index 4e43df9..a1d191b 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/Tournament.java @@ -2,6 +2,7 @@ import java.io.Serializable; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -27,7 +28,8 @@ @XmlRootElement @NamedQueries( { - @NamedQuery(name = "Tournament.findAll", query = "SELECT t FROM Tournament t"), + @NamedQuery(name = "Tournament.findAll", + query = "SELECT t FROM Tournament t"), @NamedQuery(name = "Tournament.findById", query = "SELECT t FROM Tournament t WHERE t.tournamentPK.id = :id"), @NamedQuery(name = "Tournament.findByTournamentFormatId", @@ -43,11 +45,19 @@ @NamedQuery(name = "Tournament.findByStartDate", query = "SELECT t FROM Tournament t WHERE t.startDate = :startDate"), @NamedQuery(name = "Tournament.findByEndDate", - query = "SELECT t FROM Tournament t WHERE t.endDate = :endDate") + query = "SELECT t FROM Tournament t WHERE t.endDate = :endDate"), + @NamedQuery(name = "Tournament.findBySignupDate", + query = "SELECT t FROM Tournament t WHERE t.signupDate = :signupDate"), + @NamedQuery(name = "Tournament.findBySignupTimeLimit", + query = "SELECT t FROM Tournament t WHERE t.signupTimeLimit = :signupTimeLimit"), + @NamedQuery(name = "Tournament.findByRoundTimeLimit", + query = "SELECT t FROM Tournament t WHERE t.roundTimeLimit = :roundTimeLimit"), + @NamedQuery(name = "Tournament.findByNoShowTimeLimit", + query = "SELECT t FROM Tournament t WHERE t.noShowTimeLimit = :noShowTimeLimit") }) public class Tournament implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -6583090940281361773L; @EmbeddedId protected TournamentPK tournamentPK; @Basic(optional = false) @@ -68,9 +78,17 @@ public class Tournament implements Serializable @Column(name = "lossPoints") private int lossPoints; @Column(name = "startDate") - private LocalDate startDate; + private LocalDateTime startDate; @Column(name = "endDate") - private LocalDate endDate; + private LocalDateTime endDate; + @Column(name = "signupDate") + private LocalDate signupDate; + @Column(name = "signupTimeLimit") + private Integer signupTimeLimit; + @Column(name = "roundTimeLimit") + private Integer roundTimeLimit; + @Column(name = "noShowTimeLimit") + private Integer noShowTimeLimit; @JoinColumns( { @JoinColumn(name = "format_id", referencedColumnName = "id"), @@ -122,6 +140,77 @@ public void setTournamentPK(TournamentPK tournamentPK) this.tournamentPK = tournamentPK; } + public Format getFormat() + { + return format; + } + + public void setFormat(Format format) + { + this.format = format; + } + + public TournamentFormat getTournamentFormat() + { + return tournamentFormat; + } + + public void setTournamentFormat(TournamentFormat tournamentFormat) + { + this.tournamentFormat = tournamentFormat; + } + + @XmlTransient + public List getTournamentHasTeamList() + { + return tournamentHasTeamList; + } + + public void setTournamentHasTeamList(List tournamentHasTeamList) + { + this.tournamentHasTeamList = tournamentHasTeamList; + } + + @XmlTransient + public List getRoundList() + { + return roundList; + } + + public void setRoundList(List roundList) + { + this.roundList = roundList; + } + + @Override + public int hashCode() + { + int hash = 0; + hash += (tournamentPK != null ? tournamentPK.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) + { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Tournament)) + { + return false; + } + Tournament other = (Tournament) object; + return !((this.tournamentPK == null && other.tournamentPK != null) + || (this.tournamentPK != null + && !this.tournamentPK.equals(other.tournamentPK))); + } + + @Override + public String toString() + { + return "com.github.javydreamercsw.database.storage.db.Tournament[ tournamentPK=" + + tournamentPK + " ]"; + } + public String getName() { return name; @@ -162,94 +251,63 @@ public void setLossPoints(int lossPoints) this.lossPoints = lossPoints; } - public LocalDate getStartDate() + public LocalDateTime getStartDate() { return startDate; } - public void setStartDate(LocalDate startDate) + public void setStartDate(LocalDateTime startDate) { this.startDate = startDate; } - public LocalDate getEndDate() + public LocalDateTime getEndDate() { return endDate; } - public void setEndDate(LocalDate endDate) + public void setEndDate(LocalDateTime endDate) { this.endDate = endDate; } - public Format getFormat() + public LocalDate getSignupDate() { - return format; + return signupDate; } - public void setFormat(Format format) + public void setSignupDate(LocalDate signupDate) { - this.format = format; + this.signupDate = signupDate; } - public TournamentFormat getTournamentFormat() + public Integer getSignupTimeLimit() { - return tournamentFormat; + return signupTimeLimit; } - public void setTournamentFormat(TournamentFormat tournamentFormat) + public void setSignupTimeLimit(Integer signupTimeLimit) { - this.tournamentFormat = tournamentFormat; + this.signupTimeLimit = signupTimeLimit; } - @XmlTransient - public List getTournamentHasTeamList() + public Integer getRoundTimeLimit() { - return tournamentHasTeamList; + return roundTimeLimit; } - public void setTournamentHasTeamList(List tournamentHasTeamList) + public void setRoundTimeLimit(Integer roundTimeLimit) { - this.tournamentHasTeamList = tournamentHasTeamList; + this.roundTimeLimit = roundTimeLimit; } - @XmlTransient - public List getRoundList() + public Integer getNoShowTimeLimit() { - return roundList; + return noShowTimeLimit; } - public void setRoundList(List roundList) + public void setNoShowTimeLimit(Integer noShowTimeLimit) { - this.roundList = roundList; - } - - @Override - public int hashCode() - { - int hash = 0; - hash += (tournamentPK != null ? tournamentPK.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) - { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof Tournament)) - { - return false; - } - Tournament other = (Tournament) object; - return !((this.tournamentPK == null && other.tournamentPK != null) - || (this.tournamentPK != null - && !this.tournamentPK.equals(other.tournamentPK))); - } - - @Override - public String toString() - { - return "com.github.javydreamercsw.database.storage.db.Tournament[ tournamentPK=" - + tournamentPK + " ]"; + this.noShowTimeLimit = noShowTimeLimit; } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java index 5d577c1..c436c3f 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/TournamentFormat.java @@ -1,6 +1,7 @@ package com.github.javydreamercsw.database.storage.db; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; import javax.persistence.Basic; @@ -63,10 +64,12 @@ public class TournamentFormat implements Serializable public TournamentFormat() { + tournamentList = new ArrayList<>(); } public TournamentFormat(String formatName, String implementationClass) { + this(); this.formatName = formatName; this.implementationClass = implementationClass; } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java index ab1faf3..78b88b4 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/DataBaseManager.java @@ -459,7 +459,7 @@ public static void nativeUpdateQuery(String query) public static void loadDemoData() throws Exception { Random r = new Random(); - + // Add players for (int i = 0; i < 10; i++) { @@ -473,23 +473,9 @@ public static void loadDemoData() throws Exception } } - // Add a tournaments - List formats = new ArrayList<>(); - formats.addAll(Lookup.getDefault().lookupAll(TournamentInterface.class)); - for (int i = 0; i < 10; i++) - { - Tournament t = new Tournament("Tournament " + (i + 1)); - t.setWinPoints(3); - t.setLossPoints(0); - t.setDrawPoints(1); - t.setFormat(FormatService.getInstance().getAll().get(0)); - t.setTournamentFormat(TournamentService.getInstance() - .findFormat(formats.get(r.nextInt(formats.size())).getName())); - TournamentService.getInstance().saveTournament(t); - } - IGame gameAPI = Lookup.getDefault().lookup(IGame.class); - Optional fg = GameService.getInstance().findGameByName(gameAPI.getName()); + Optional fg + = GameService.getInstance().findGameByName(gameAPI.getName()); Game game; if (fg.isPresent()) { @@ -518,9 +504,36 @@ public static void loadDemoData() throws Exception FormatService.getInstance().saveFormat(newFormat); } } + + // Add a tournaments + List formats = new ArrayList<>(); + formats.addAll(Lookup.getDefault().lookupAll(TournamentInterface.class)); + + for (TournamentInterface format : formats) + { + TournamentFormat tf = new TournamentFormat(format.getName(), + format.getClass().getCanonicalName()); + TournamentService.getInstance().saveTournamentFormat(tf); + } + + for (int i = 0; i < 10; i++) + { + // Set a random start date: + int startDay = r.nextInt(31); + Tournament t = new Tournament("Tournament " + (i + 1)); + t.setWinPoints(3); + t.setLossPoints(0); + t.setDrawPoints(1); + + t.setFormat(FormatService.getInstance().getAll().get(0)); + t.setTournamentFormat(TournamentService.getInstance() + .findFormat(formats.get(r.nextInt(formats.size())).getName())); + TournamentService.getInstance().saveTournament(t); + } + List formatList = FormatService.getInstance() .findFormatByGame(gameAPI.getName()); - + // Add matches for (int i = 0; i < 10; i++) { @@ -562,26 +575,24 @@ public static void loadDemoData() throws Exception } /** - * Load stuff from the Lookup + * Load stuff from the Lookup. + * + * @throws java.lang.Exception */ - public static void load() + public static void load() throws Exception { - Lookup.getDefault().lookupAll(TournamentInterface.class).forEach(format -> + for (TournamentInterface format : Lookup.getDefault() + .lookupAll(TournamentInterface.class)) { // Register the tournament formats if (TournamentService.getInstance().findFormat(format.getName()) == null) { - try { - TournamentFormat tf = new TournamentFormat(format.getName(), - format.getClass().getCanonicalName()); - TournamentService.getInstance().addFormat(tf); - } - catch (Exception ex) { - Exceptions.printStackTrace(ex); - } + TournamentFormat tf = new TournamentFormat(format.getName(), + format.getClass().getCanonicalName()); + TournamentService.getInstance().addFormat(tf); } - }); - Lookup.getDefault().lookupAll(IGame.class).forEach(gameAPI -> + } + for (IGame gameAPI : Lookup.getDefault().lookupAll(IGame.class)) { // Add game to DB if not there Optional result @@ -599,7 +610,7 @@ public static void load() } //Load formats - gameAPI.gameFormats().forEach(format -> + for (GameFormat format : gameAPI.gameFormats()) { // Check if it exists in the databse Optional f @@ -607,21 +618,14 @@ public static void load() .findFormatForGame(gameAPI.getName(), format.getName()); if (!f.isPresent()) { - try - { - // Let's create it. - Format newFormat = new Format(); - newFormat.setName(format.getName()); - newFormat.setDescription(format.getDescription()); - newFormat.setGame(game); - FormatService.getInstance().saveFormat(newFormat); - } - catch (Exception ex) - { - Exceptions.printStackTrace(ex); - } + // Let's create it. + Format newFormat = new Format(); + newFormat.setName(format.getName()); + newFormat.setDescription(format.getDescription()); + newFormat.setGame(game); + FormatService.getInstance().saveFormat(newFormat); } - }); - }); + } + } } } diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/LocalDateTimeAttributeConverter.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/LocalDateTimeAttributeConverter.java new file mode 100644 index 0000000..e34bdfb --- /dev/null +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/LocalDateTimeAttributeConverter.java @@ -0,0 +1,22 @@ +package com.github.javydreamercsw.database.storage.db.server; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +@Converter(autoApply = true) +public class LocalDateTimeAttributeConverter + implements AttributeConverter { + + @Override + public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) { + return (locDateTime == null ? null : Timestamp.valueOf(locDateTime)); + } + + @Override + public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) { + return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime()); + } +} diff --git a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java index f1cb9c3..2f89f59 100644 --- a/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java +++ b/Database-Storage/src/main/java/com/github/javydreamercsw/database/storage/db/server/TournamentService.java @@ -1,6 +1,6 @@ package com.github.javydreamercsw.database.storage.db.server; -import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -236,7 +236,7 @@ public List getAll() public void deleteRound(Round round) throws IllegalOrphanException, NonexistentEntityException { - for (MatchEntry me:round.getMatchEntryList()) + for (MatchEntry me : round.getMatchEntryList()) { MatchService.getInstance().deleteMatch(me); } @@ -361,7 +361,7 @@ public void startNextRound(Tournament tournament) throws TournamentException if (tournament.getRoundList().isEmpty()) { // Mark as started. - tournament.setStartDate(LocalDate.now()); + tournament.setStartDate(LocalDateTime.now()); saveTournament(tournament); } @@ -406,7 +406,7 @@ public void startNextRound(Tournament tournament) throws TournamentException { // Tournament is over! // Mark as ended. - tournament.setEndDate(LocalDate.now()); + tournament.setEndDate(LocalDateTime.now()); saveTournament(tournament); } } @@ -582,4 +582,34 @@ public void checkStatus(Tournament t) { } + + /** + * Save a tournament Format. + * + * @param tf format to save + * @throws NonexistentEntityException If editing and it doesn't exist. + * @throws Exception If something goes wrong persisting to database. + */ + public void saveTournamentFormat(TournamentFormat tf) + throws NonexistentEntityException, Exception + { + if (tf.getId() == null) + { + tfc.create(tf); + } + else + { + tfc.edit(tf); + } + } + + /** + * Get all Tournament Formats. + * + * @return All formats in the database. + */ + public List getAllFormats() + { + return tfc.findTournamentFormatEntities(); + } } diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java index 05139b8..2437216 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TestTournamentFormat.java @@ -33,7 +33,7 @@ public TestTournamentFormat(int winPoints, int lossPoints, int drawPoints) @Override public String getName() { - return "Dummy Tournament"; + return "Dummy Tournament Format"; } @Override diff --git a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java index b3de3cd..3907e53 100644 --- a/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java +++ b/Database-Storage/src/test/java/com/github/javydreamercsw/database/storage/db/server/TournamentServiceTest.java @@ -1,7 +1,10 @@ package com.github.javydreamercsw.database.storage.db.server; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.testng.Assert.*; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -108,6 +111,21 @@ public void testSaveAndDelete() throws IllegalOrphanException, assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) .size(), 1); + LocalDateTime now = LocalDateTime.now(); + t2.setStartDate(now); + t2.setEndDate(now.plusHours(1)); + t2.setSignupTimeLimit(10); + t2.setRoundTimeLimit(30); + + TournamentService.getInstance().saveTournament(t2); + + Tournament retrieved = TournamentService.getInstance() + .findTournament(t2.getTournamentPK()); + assertThat(t2.getStartDate(), equalTo(retrieved.getStartDate())); + assertThat(t2.getEndDate(), equalTo(retrieved.getEndDate())); + assertThat(t2.getSignupTimeLimit(), equalTo(retrieved.getSignupTimeLimit())); + assertThat(t2.getRoundTimeLimit(), equalTo(retrieved.getRoundTimeLimit())); + TournamentService.getInstance().deleteTournament(t2); assertEquals(TournamentService.getInstance().findTournaments(t2.getName()) @@ -169,7 +187,7 @@ public Object[][] getScenarios() { 8, 1, 3 // Eight teams of 1 people. Should be done in 3 rounds. }, - { + { 16, 2, 3 // Eight teams of 1 people. Should be done in 3 rounds. } }; From 4f2fdb66130bee840780cbebe8cc4adf2190fd1b Mon Sep 17 00:00:00 2001 From: Javier Ortiz Date: Wed, 19 Dec 2018 08:31:54 -0600 Subject: [PATCH 20/25] Database changes for tournament features. --- Database-Storage/DB.mwb | Bin 29435 -> 29418 bytes Database-Storage/DB.mwb.bak | Bin 29273 -> 29423 bytes .../database/storage/db/MatchResult.java | 16 +++---- .../database/storage/db/Record.java | 6 +-- .../database/storage/db/Tournament.java | 41 +++++++++++------- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/Database-Storage/DB.mwb b/Database-Storage/DB.mwb index 237e92d8ca4d62f2491a4b13123dc613f7021b15..b4730801694147246a4af5d14a35ff30744828bf 100644 GIT binary patch delta 25469 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 delta 25477 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 Sk}50;Li79?1Xc=p|Nj7~B2>u$ diff --git a/Database-Storage/DB.mwb.bak b/Database-Storage/DB.mwb.bak index 2c6ced3eacb056d52b80901224bfb9ab9527b86d..9839e39b087a522b66110e9f594e0dfd744869be 100644 GIT binary patch delta 25583 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 DWSLDD delta 25525 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