summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2025-11-13 08:20:04 -0500
committersowgro <tpoke.ferrari@gmail.com>2025-11-13 08:20:04 -0500
commitc1bf473e5c6735ae00c3fbfec0f9d16c421387db (patch)
tree703e1bfaf95d274ff10d9946e63d2e4e39ae9d6f /src/main/java
parentc8e3d79f09670a94c0a2f503ca6c78f9913a1669 (diff)
parentaf23c48329b749ba3d0a4fcd841723d55a16ae95 (diff)
downloaddesignproject-design-6-c1bf473e5c6735ae00c3fbfec0f9d16c421387db.tar.gz
designproject-design-6-c1bf473e5c6735ae00c3fbfec0f9d16c421387db.tar.bz2
designproject-design-6-c1bf473e5c6735ae00c3fbfec0f9d16c421387db.zip
Merge remote-tracking branch 'origin/league-model'
# Conflicts: # src/main/java/design/controller/userinput/menus/MainMenu.java # src/main/java/design/model/Golfer.java # src/test/java/design/model/ClubTest.java # src/test/java/design/model/GolferTest.java
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/design/controller/userinput/menus/LeageMenu.java30
-rw-r--r--src/main/java/design/controller/userinput/menus/MainMenu.java4
-rw-r--r--src/main/java/design/controller/userinput/menus/ManageClubs.java3
-rw-r--r--src/main/java/design/controller/userinput/menus/SelectLeague.java83
-rw-r--r--src/main/java/design/model/Club.java18
-rw-r--r--src/main/java/design/model/Invite.java25
-rw-r--r--src/main/java/design/model/League.java90
-rw-r--r--src/main/java/design/model/Match.java57
-rw-r--r--src/main/java/design/model/ScrambleLeague.java46
-rw-r--r--src/main/java/design/model/StrokeLeague.java36
-rw-r--r--src/main/java/design/model/Team.java40
-rw-r--r--src/main/java/design/persistence/JSONLeagueDatabase.java102
-rw-r--r--src/main/java/design/persistence/JSONPersonalDatabase.java49
-rw-r--r--src/main/java/design/persistence/LeagueDatabase.java21
-rw-r--r--src/main/java/design/persistence/MasterDatabase.java2
-rw-r--r--src/main/java/design/persistence/Serializers.java79
16 files changed, 640 insertions, 45 deletions
diff --git a/src/main/java/design/controller/userinput/menus/LeageMenu.java b/src/main/java/design/controller/userinput/menus/LeageMenu.java
new file mode 100644
index 0000000..d9afa91
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/LeageMenu.java
@@ -0,0 +1,30 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.League;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LeageMenu extends Menu {
+ private final League league;
+
+ public LeageMenu(League league) {
+ this.league = league;
+ }
+
+ @Override
+ public String getTitle() {
+ return "League Menu";
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ List<MenuOption> options = new ArrayList<>();
+ options.add(new MenuOption("statistics...", () -> {}));
+ options.add(new MenuOption("leaderboard...", () -> {}));
+ options.add(new MenuOption("log round...", () -> {}));
+ return options;
+ }
+}
diff --git a/src/main/java/design/controller/userinput/menus/MainMenu.java b/src/main/java/design/controller/userinput/menus/MainMenu.java
index 8a30258..75ad88f 100644
--- a/src/main/java/design/controller/userinput/menus/MainMenu.java
+++ b/src/main/java/design/controller/userinput/menus/MainMenu.java
@@ -38,8 +38,8 @@ public class MainMenu extends Menu {
new MenuOption("manage courses...", () -> new ManageCourses().present()),
new MenuOption("manage clubs...", () -> new ManageClubs().present()),
new MenuOption("statistics...", () -> new StatisticsMenu().present()),
- new MenuOption("log round...", () -> new HolePlayMenu().present())
-
+ new MenuOption("log round...", () -> new HolePlayMenu().present()),
+ new MenuOption("League play...", () -> new SelectLeague().present())
);
}
}
diff --git a/src/main/java/design/controller/userinput/menus/ManageClubs.java b/src/main/java/design/controller/userinput/menus/ManageClubs.java
index d186cac..9c23433 100644
--- a/src/main/java/design/controller/userinput/menus/ManageClubs.java
+++ b/src/main/java/design/controller/userinput/menus/ManageClubs.java
@@ -65,7 +65,8 @@ public class ManageClubs extends Menu {
selector.present();
Club.ClubType type = selector.getResult();
- golfer.addClub(manufacture, nickname, type);
+ Club c = new Club(manufacture, nickname, type);
+ golfer.addClub(c);
// Add club to JSON
try {
diff --git a/src/main/java/design/controller/userinput/menus/SelectLeague.java b/src/main/java/design/controller/userinput/menus/SelectLeague.java
new file mode 100644
index 0000000..08f6c91
--- /dev/null
+++ b/src/main/java/design/controller/userinput/menus/SelectLeague.java
@@ -0,0 +1,83 @@
+package design.controller.userinput.menus;
+
+import design.controller.userinput.Menu;
+import design.controller.userinput.MenuOption;
+import design.model.Golfer;
+import design.model.League;
+import design.model.ScrambleLeague;
+import design.model.StrokeLeague;
+import design.persistence.LeagueDatabase;
+import design.runtime.Session;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class SelectLeague extends Menu {
+ private final Golfer golfer = Session.getCurrentGolfer();
+
+ @Override
+ public String getTitle() {
+ return "Select League";
+ }
+
+ @Override
+ public List<MenuOption> getMenuOptions() {
+ List<MenuOption> options = new ArrayList<>();
+ for (League l : LeagueDatabase.instance().getLeagues()) {
+ options.add(new MenuOption(l.getName(), () -> {
+ if (l instanceof ScrambleLeague sl && sl.locateTeam(golfer) == null) {
+ Scanner sc = new Scanner(System.in);
+ System.out.print("You are not a member of a team for this league. Would you like to create one (Y/n): ");
+ if (sc.next().equals("n")) {
+ new MainMenu().present();
+ } else {
+ // create team
+ }
+ } else {
+ new LeageMenu(l).present();
+ }
+ }));
+ }
+ options.add(new MenuOption("<create>", this::createLeagueWizard));
+ return options;
+ }
+
+ private void createLeagueWizard() {
+ try {
+ Scanner scanner = new Scanner(System.in);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+ System.out.print("Enter league name: ");
+ String name = scanner.nextLine();
+
+ System.out.print("Enter registration date (yyyy-MM-dd): ");
+ Date registrationDate = dateFormat.parse(scanner.nextLine());
+
+ System.out.print("Enter start date (yyyy-MM-dd): ");
+ Date startDate = dateFormat.parse(scanner.nextLine());
+
+ System.out.print("Enter end date (yyyy-MM-dd): ");
+ Date endDate = dateFormat.parse(scanner.nextLine());
+
+ Golfer owner = Session.getCurrentGolfer();
+
+ System.out.print("Enter format (stroke/scramble): ");
+ String scramble = scanner.nextLine();
+
+ League league;
+ switch (scramble) {
+ case "scramble" -> league = new ScrambleLeague(name, registrationDate, startDate, endDate, owner);
+ case "stroke" -> league = new StrokeLeague(name, registrationDate, startDate, endDate, owner);
+ default -> throw new RuntimeException();
+ }
+ LeagueDatabase.instance().addLeague(league);
+ } catch (ParseException ex) {
+ System.out.println("Invalid format");
+ } catch (IOException ex) {
+ System.out.println("Error writing to file");
+ }
+ this.present();
+ }
+}
diff --git a/src/main/java/design/model/Club.java b/src/main/java/design/model/Club.java
index b12fd99..c19811c 100644
--- a/src/main/java/design/model/Club.java
+++ b/src/main/java/design/model/Club.java
@@ -1,5 +1,6 @@
package design.model;
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@@ -21,18 +22,26 @@ public class Club {
PUTTER
}
- private final int id;
+ private int id;
private final String manufacture;
private final String nickname;
private final ClubType clubType;
- public Club(int id, String manufacture, String nickname, ClubType clubType) {
+ @JsonCreator
+ private Club(int id, String manufacture, String nickname, ClubType clubType) {
this.id = id;
this.manufacture = manufacture;
this.nickname = nickname;
this.clubType = clubType;
}
+ public Club(String manufacture, String nickname, ClubType clubType) {
+ this.id = -1;
+ this.manufacture = manufacture;
+ this.nickname = nickname;
+ this.clubType = clubType;
+ }
+
public int getId() {
return id;
}
@@ -49,6 +58,11 @@ public class Club {
return clubType;
}
+ public void setId(int id) {
+ assert this.id == -1;
+ this.id = id;
+ }
+
@Override
public String toString() {
return String.format("#%d %s - %s (%s)", id, nickname, manufacture, clubType);
diff --git a/src/main/java/design/model/Invite.java b/src/main/java/design/model/Invite.java
new file mode 100644
index 0000000..479f520
--- /dev/null
+++ b/src/main/java/design/model/Invite.java
@@ -0,0 +1,25 @@
+package design.model;
+
+import java.util.Date;
+
+public class Invite {
+ private final Team team;
+ private final Date sendDate;
+
+ public Invite(Team team, Date sendDate) {
+ this.team = team;
+ this.sendDate = sendDate;
+ }
+
+ public Team getTeam() {
+ return team;
+ }
+
+ public Date getSendDate() {
+ return sendDate;
+ }
+
+ public void accept(Golfer g) {
+ team.addMember(g);
+ }
+}
diff --git a/src/main/java/design/model/League.java b/src/main/java/design/model/League.java
new file mode 100644
index 0000000..881e25f
--- /dev/null
+++ b/src/main/java/design/model/League.java
@@ -0,0 +1,90 @@
+package design.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@JsonTypeInfo(
+ use = JsonTypeInfo.Id.NAME,
+ include = JsonTypeInfo.As.PROPERTY,
+ property = "type"
+)
+@JsonSubTypes({
+ @JsonSubTypes.Type(value = ScrambleLeague.class, name = "scramble"),
+ @JsonSubTypes.Type(value = StrokeLeague.class, name = "stroke")
+})
+public abstract class League {
+ private int id;
+ private final String name;
+ private final Date registrationDate;
+ private final Date startDate;
+ private final Date endDate;
+ private final Golfer owner;
+ private final List<Match> schedule;
+
+ @JsonCreator
+ protected League(int id, String name, Date registrationDate, Date startDate, Date endDate, Golfer owner, List<Match> schedule) {
+ this.id = id;
+ this.name = name;
+ this.registrationDate = registrationDate;
+ this.startDate = startDate;
+ this.endDate = endDate;
+ this.owner = owner;
+ this.schedule = schedule != null ? schedule : new ArrayList<>();
+ }
+
+ public League(String name, Date registrationDate, Date startDate, Date endDate, Golfer owner) {
+ this.id = -1;
+ this.name = name;
+ this.registrationDate = registrationDate;
+ this.startDate = startDate;
+ this.endDate = endDate;
+ this.owner = owner;
+ this.schedule = new ArrayList<>();
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Date getRegistrationDate() {
+ return registrationDate;
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+
+ public Golfer getOwner() {
+ return owner;
+ }
+
+ public Match[] getSchedule() {
+ return schedule.toArray(Match[]::new);
+ }
+
+ public void addMatchToSchedule(Match match) {
+ Date date = match.getDateScheduled();
+ if(date.after(endDate)){
+ throw new IllegalArgumentException("Cannot create match after league has ended");
+ }
+ schedule.add(match);
+ }
+
+ public void setId(int id) {
+ assert this.id == -1;
+ this.id = id;
+ }
+}
diff --git a/src/main/java/design/model/Match.java b/src/main/java/design/model/Match.java
new file mode 100644
index 0000000..4f01c98
--- /dev/null
+++ b/src/main/java/design/model/Match.java
@@ -0,0 +1,57 @@
+package design.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class Match {
+ private final Course course;
+ private final Date dateScheduled;
+ private final LocalDateTime start;
+ private final int holeCount;
+ private final List<Round> rounds;
+
+ @JsonCreator
+ private Match(Course course, Date dateScheduled, LocalDateTime start, int holeCount, List<Round> rounds) {
+ this.course = course;
+ this.dateScheduled = dateScheduled;
+ this.start = start;
+ this.holeCount = holeCount;
+ this.rounds = rounds;
+ }
+
+ public Match(Course course, Date dateScheduled, LocalDateTime start, int holeCount) {
+ this.course = course;
+ this.dateScheduled = dateScheduled;
+ this.start = start;
+ this.holeCount = holeCount;
+ this.rounds = new ArrayList<>();
+ }
+
+ public Course getCourse() {
+ return course;
+ }
+
+ public Date getDateScheduled() {
+ return dateScheduled;
+ }
+
+ public LocalDateTime getStart() {
+ return start;
+ }
+
+ public int getHoleCount() {
+ return holeCount;
+ }
+
+ public boolean addRound(Round round) {
+ return rounds.add(round);
+ }
+
+ public Round[] getRounds() {
+ return rounds.toArray(Round[]::new);
+ }
+}
diff --git a/src/main/java/design/model/ScrambleLeague.java b/src/main/java/design/model/ScrambleLeague.java
new file mode 100644
index 0000000..d372264
--- /dev/null
+++ b/src/main/java/design/model/ScrambleLeague.java
@@ -0,0 +1,46 @@
+package design.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+@JsonTypeName("scramble")
+public class ScrambleLeague extends League {
+ private final List<Team> participants;
+
+ @JsonCreator
+ private ScrambleLeague(int id, String name, Date registrationDate, Date startDate, Date endDate, Golfer owner, List<Team> participants, List<Match> schedule) {
+ super(id, name, registrationDate, startDate, endDate, owner, schedule);
+ this.participants = participants;
+ }
+
+ public ScrambleLeague(String name, Date registrationDate, Date startDate, Date endDate, Golfer owner) {
+ super(name, registrationDate, startDate, endDate, owner);
+ this.participants = new ArrayList<>();
+ }
+
+ public boolean addParticipants(Team e) {
+ return participants.add(e);
+ }
+
+ public boolean removeParticipants(Team o) {
+ return participants.remove(o);
+ }
+
+ public Team[] getParticipants() {
+ return participants.toArray(Team[]::new);
+ }
+
+ public Team locateTeam(Golfer golfer) {
+ for (Team participant : participants) {
+ if (List.of(participant.getMembers()).contains(golfer)) {
+ return participant;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/design/model/StrokeLeague.java b/src/main/java/design/model/StrokeLeague.java
new file mode 100644
index 0000000..2b787b5
--- /dev/null
+++ b/src/main/java/design/model/StrokeLeague.java
@@ -0,0 +1,36 @@
+package design.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@JsonTypeName("stroke")
+public class StrokeLeague extends League {
+ private final List<Golfer> participants;
+
+ @JsonCreator
+ private StrokeLeague(int id, String name, Date registrationDate, Date startDate, Date endDate, Golfer owner, List<Golfer> participants, List<Match> schedule) {
+ super(id, name, registrationDate, startDate, endDate, owner, schedule);
+ this.participants = participants;
+ }
+
+ public StrokeLeague(String name, Date registrationDate, Date startDate, Date endDate, Golfer owner) {
+ super(name, registrationDate, startDate, endDate, owner);
+ this.participants = new ArrayList<>();
+ }
+
+ public boolean addParticipants(Golfer e) {
+ return participants.add(e);
+ }
+
+ public boolean removeParticipants(Golfer o) {
+ return participants.remove(o);
+ }
+
+ public Golfer[] getParticipants() {
+ return participants.toArray(Golfer[]::new);
+ }
+}
diff --git a/src/main/java/design/model/Team.java b/src/main/java/design/model/Team.java
new file mode 100644
index 0000000..53b276e
--- /dev/null
+++ b/src/main/java/design/model/Team.java
@@ -0,0 +1,40 @@
+package design.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Team {
+ private String name;
+ private final List<Golfer> members;
+ private final Golfer owner;
+
+ public Team(String name, Golfer owner) {
+ this.name = name;
+ this.owner = owner;
+ this.members = new ArrayList<>();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Golfer[] getMembers() {
+ return members.toArray(Golfer[]::new);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean addMember(Golfer golfer) {
+ return members.add(golfer);
+ }
+
+ public boolean removeMember(Golfer g) {
+ return members.remove(g);
+ }
+
+ public Golfer getOwner() {
+ return owner;
+ }
+}
diff --git a/src/main/java/design/persistence/JSONLeagueDatabase.java b/src/main/java/design/persistence/JSONLeagueDatabase.java
new file mode 100644
index 0000000..8a55065
--- /dev/null
+++ b/src/main/java/design/persistence/JSONLeagueDatabase.java
@@ -0,0 +1,102 @@
+package design.persistence;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.core.StreamReadFeature;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
+import design.model.Course;
+import design.model.Golfer;
+import design.model.League;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class JSONLeagueDatabase implements LeagueDatabase {
+
+ private static JSONLeagueDatabase INSTANCE;
+
+ public static JSONLeagueDatabase instance() {
+ if (INSTANCE == null) {
+ INSTANCE = new JSONLeagueDatabase("data/leaguedb.json");
+ }
+ return INSTANCE;
+ }
+
+ private final Map<Integer, League> cache;
+ private final ObjectMapper mapper;
+ private final File file;
+ private int nextLeagueID;
+
+ public JSONLeagueDatabase(String filename) {
+ this.file = new File(filename);
+ this.cache = new HashMap<>();
+ this.mapper = JsonMapper.builder().enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION).build();
+
+ SimpleModule module = new SimpleModule();
+ module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer());
+ module.addSerializer(Course.class, new Serializers.CourseIdSerializer());
+ module.addDeserializer(Golfer.class, new Serializers.GolferUsernameDeserializer());
+ module.addSerializer(Golfer.class, new Serializers.GolferUsernameSerializer());
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ mapper.registerModule(module);
+ mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
+ mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));
+ mapper.registerModule(new JavaTimeModule());
+
+ try {
+ load();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ this.nextLeagueID = cache.values().stream().mapToInt(League::getId).max().orElse(0) + 1;
+ }
+
+ private void load() throws IOException {
+ League[] data = mapper.readValue(file, League[].class);
+ cache.clear();
+ Arrays.stream(data).forEach(i -> cache.put(i.getId(), i));
+ }
+
+ private void save() throws IOException {
+ League[] data = cache.values().toArray(League[]::new);
+ mapper.writer(new Serializers.CustomPrettyPrinter()).writeValue(file, data);
+ }
+
+ @Override
+ public League getLeague(int id) {
+ return cache.get(id);
+ }
+
+ @Override
+ public League[] getLeagues() {
+ return cache.values().toArray(League[]::new);
+ }
+
+ @Override
+ public void addLeague(League league) throws IOException {
+ league.setId(nextLeagueID++);
+ cache.putIfAbsent(league.getId(), league);
+ save();
+ }
+
+ @Override
+ public void removeLeague(League league) throws IOException {
+ cache.remove(league.getId());
+ save();
+ }
+
+ @Override
+ public void updateLeague(League league) throws IOException {
+ cache.put(league.getId(), league);
+ save();
+ }
+}
diff --git a/src/main/java/design/persistence/JSONPersonalDatabase.java b/src/main/java/design/persistence/JSONPersonalDatabase.java
index 70aa1ab..30c280a 100644
--- a/src/main/java/design/persistence/JSONPersonalDatabase.java
+++ b/src/main/java/design/persistence/JSONPersonalDatabase.java
@@ -3,21 +3,18 @@ package design.persistence;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.util.DefaultIndenter;
-import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.core.StreamReadFeature;
import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
-import design.model.Club;
import design.model.Course;
import design.model.Golfer;
+import design.model.League;
import java.io.File;
import java.io.IOException;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -39,15 +36,17 @@ public class JSONPersonalDatabase implements PersonalDatabase {
private JSONPersonalDatabase(String filename) {
this.file = new File(filename);
this.cache = new HashMap<>();
- this.mapper = new ObjectMapper();
+ this.mapper = JsonMapper.builder().enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION).build();;
// TODO: Once the saved JSON matches the model, consider removing.
// TEMP: tolerate unknown props while the model stabilizes
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SimpleModule module = new SimpleModule();
- module.addDeserializer(Course.class, new CourseIdDeserializer());
- module.addSerializer(Course.class, new CourseIdSerializer());
+ module.addDeserializer(Course.class, new Serializers.CourseIdDeserializer());
+ module.addSerializer(Course.class, new Serializers.CourseIdSerializer());
+ module.addSerializer(League.class, new Serializers.LeagueIDSerializer());
+ module.addDeserializer(League.class, new Serializers.LeagueIDDeserializer());
mapper.registerModule(module);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES));
@@ -70,7 +69,7 @@ public class JSONPersonalDatabase implements PersonalDatabase {
private void save() throws IOException {
Golfer[] data = cache.values().toArray(Golfer[]::new);
- mapper.writer(new CustomPrettyPrinter()).writeValue(file, data);
+ mapper.writer(new Serializers.CustomPrettyPrinter()).writeValue(file, data);
}
// turns that collection into a real array of golfers
@@ -101,34 +100,4 @@ public class JSONPersonalDatabase implements PersonalDatabase {
cache.put(golfer.getUsername(), golfer);
save();
}
-
- private static class CourseIdSerializer extends JsonSerializer<Course> {
- @Override
- public void serialize(Course course, JsonGenerator gen, SerializerProvider serializers) throws IOException {
- gen.writeNumber(course.getId());
- }
- }
-
- private static class CourseIdDeserializer extends JsonDeserializer<Course> {
- MasterDatabase masterDB = MasterDatabase.instance();
-
- @Override
- public Course deserialize(JsonParser p, DeserializationContext context) throws IOException {
- int id = p.getValueAsInt();
- return masterDB.getCourse(id);
- }
- }
-
- private static class CustomPrettyPrinter extends DefaultPrettyPrinter {
- public CustomPrettyPrinter() {
- super._arrayIndenter = new DefaultIndenter();
- super._objectFieldValueSeparatorWithSpaces = _separators.getObjectFieldValueSeparator() + " ";
- super._arrayEmptySeparator = "";
- }
-
- @Override
- public CustomPrettyPrinter createInstance() {
- return new CustomPrettyPrinter();
- }
- }
}
diff --git a/src/main/java/design/persistence/LeagueDatabase.java b/src/main/java/design/persistence/LeagueDatabase.java
new file mode 100644
index 0000000..953624d
--- /dev/null
+++ b/src/main/java/design/persistence/LeagueDatabase.java
@@ -0,0 +1,21 @@
+package design.persistence;
+
+import design.model.League;
+
+import java.io.IOException;
+
+public interface LeagueDatabase {
+ static LeagueDatabase instance() {
+ return JSONLeagueDatabase.instance();
+ }
+
+ League getLeague(int id);
+
+ League[] getLeagues();
+
+ void addLeague(League league) throws IOException;
+
+ void removeLeague(League league) throws IOException;
+
+ void updateLeague(League league) throws IOException;
+}
diff --git a/src/main/java/design/persistence/MasterDatabase.java b/src/main/java/design/persistence/MasterDatabase.java
index 59e3ebd..86e326b 100644
--- a/src/main/java/design/persistence/MasterDatabase.java
+++ b/src/main/java/design/persistence/MasterDatabase.java
@@ -10,6 +10,8 @@ public interface MasterDatabase {
}
Course[] getCourses();
+
CourseList getCourseList(); // unique from courses as this is a composite of ICourses.
+
Course getCourse(int id);
}
diff --git a/src/main/java/design/persistence/Serializers.java b/src/main/java/design/persistence/Serializers.java
new file mode 100644
index 0000000..3940b44
--- /dev/null
+++ b/src/main/java/design/persistence/Serializers.java
@@ -0,0 +1,79 @@
+package design.persistence;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.util.DefaultIndenter;
+import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import design.model.Course;
+import design.model.Golfer;
+import design.model.League;
+
+import java.io.IOException;
+
+public class Serializers {
+ public static class CustomPrettyPrinter extends DefaultPrettyPrinter {
+ public CustomPrettyPrinter() {
+ super._arrayIndenter = new DefaultIndenter();
+ super._objectFieldValueSeparatorWithSpaces = _separators.getObjectFieldValueSeparator() + " ";
+ super._arrayEmptySeparator = "";
+ }
+
+ @Override
+ public CustomPrettyPrinter createInstance() {
+ return new CustomPrettyPrinter();
+ }
+ }
+
+ public static class CourseIdSerializer extends JsonSerializer<Course> {
+ @Override
+ public void serialize(Course course, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeNumber(course.getId());
+ }
+ }
+
+ public static class CourseIdDeserializer extends JsonDeserializer<Course> {
+ @Override
+ public Course deserialize(JsonParser p, DeserializationContext context) throws IOException {
+ MasterDatabase masterDB = MasterDatabase.instance();
+ int id = p.getValueAsInt();
+ return masterDB.getCourse(id);
+ }
+ }
+
+ public static class LeagueIDSerializer extends JsonSerializer<League> {
+ @Override
+ public void serialize(League value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeNumber(value.getId());
+ }
+ }
+
+ public static class LeagueIDDeserializer extends JsonDeserializer<League> {
+ @Override
+ public League deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
+ LeagueDatabase leagueDB = LeagueDatabase.instance();
+ int id = p.getValueAsInt();
+ return leagueDB.getLeague(id);
+ }
+ }
+
+ public static class GolferUsernameSerializer extends JsonSerializer<Golfer> {
+ @Override
+ public void serialize(Golfer course, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeString(course.getUsername());
+ }
+ }
+
+ public static class GolferUsernameDeserializer extends JsonDeserializer<Golfer> {
+
+ @Override
+ public Golfer deserialize(JsonParser p, DeserializationContext context) throws IOException {
+ PersonalDatabase personalDB = PersonalDatabase.instance();
+ String username = p.getValueAsString();
+ return personalDB.getGolfer(username);
+ }
+ }
+}