[LIB-13] Tournament and game formats for JSON parsing
authorgotty <gotty@hedgecode.org>
Wed, 15 Jan 2020 01:27:42 +0000 (04:27 +0300)
committergotty <gotty@hedgecode.org>
Wed, 15 Jan 2020 01:27:42 +0000 (04:27 +0300)
26 files changed:
src/main/java/org/hedgecode/chess/scanner/format/ArenaFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/BaseFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/Format.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/FormatBuilder.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/Game.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/GameData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/GameFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/IndexData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/Move.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/Player.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/Room.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/RoomData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/format/TournamentFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/AbstractBaseFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/AbstractPGNFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONArenaFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONFormatBuilder.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONGame.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameFormat.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONIndexData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONMove.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONPlayer.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoom.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoomData.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/json/format/JSONTournamentFormat.java [new file with mode: 0644]

diff --git a/src/main/java/org/hedgecode/chess/scanner/format/ArenaFormat.java b/src/main/java/org/hedgecode/chess/scanner/format/ArenaFormat.java
new file mode 100644 (file)
index 0000000..ae27bbc
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * ArenaFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface ArenaFormat extends BaseFormat {
+
+    IndexData indexData();
+
+    String findTournament(String tournamentName);
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/BaseFormat.java b/src/main/java/org/hedgecode/chess/scanner/format/BaseFormat.java
new file mode 100644 (file)
index 0000000..be970c9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * BaseFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface BaseFormat {
+
+    String baseUrl();
+
+    String arenaPath();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/Format.java b/src/main/java/org/hedgecode/chess/scanner/format/Format.java
new file mode 100644 (file)
index 0000000..5cd8d6c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+import org.hedgecode.chess.scanner.spi.ServiceRegistry;
+
+/**
+ * Format
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class Format {
+
+    private static Format _instance;
+
+    private final FormatBuilder formatBuilder;
+
+    private Format() {
+        formatBuilder = ServiceRegistry.singleProvider(
+                FormatBuilder.class
+        );
+    }
+
+    public static GameFormat formatGame(String game) {
+        return getFormat().builder().buildGame(game);
+    }
+
+    public static TournamentFormat formatTournament(String tournament) {
+        return getFormat().builder().buildTournament(tournament);
+    }
+
+    public static ArenaFormat formatArena(String arena) {
+        return getFormat().builder().buildArena(arena);
+    }
+
+    private FormatBuilder builder() {
+        return formatBuilder;
+    }
+
+    private static Format getFormat() {
+        if (_instance == null) {
+            _instance = new Format();
+        }
+        return _instance;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/FormatBuilder.java b/src/main/java/org/hedgecode/chess/scanner/format/FormatBuilder.java
new file mode 100644 (file)
index 0000000..8830d44
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * FormatBuilder
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface FormatBuilder {
+
+    GameFormat buildGame(String game);
+
+    TournamentFormat buildTournament(String tournament);
+
+    ArenaFormat buildArena(String arena);
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/Game.java b/src/main/java/org/hedgecode/chess/scanner/format/Game.java
new file mode 100644 (file)
index 0000000..ee4ae3e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+import java.util.Date;
+
+/**
+ * Game
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Game {
+
+    int id();
+
+    int roomId();
+
+    String slug();
+
+    String roundSlug();
+
+    int whiteId();
+
+    int blackId();
+
+    int whiteElo();
+
+    int blackElo();
+
+    Date startAt();
+
+    Date endAt();
+
+    Date updateAt();
+
+    String result();
+
+    int table();
+
+    int board();
+
+    Player white();
+
+    Player black();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/GameData.java b/src/main/java/org/hedgecode/chess/scanner/format/GameData.java
new file mode 100644 (file)
index 0000000..bb265bd
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * GameData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface GameData {
+
+    Game game();
+
+    Room room();
+
+    Move[] moves();
+
+    String formatMoves();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/GameFormat.java b/src/main/java/org/hedgecode/chess/scanner/format/GameFormat.java
new file mode 100644 (file)
index 0000000..95bffef
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+import org.hedgecode.chess.scanner.entity.PGNEntity;
+
+/**
+ * GameFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface GameFormat extends PGNEntity, BaseFormat {
+
+    String id();
+
+    GameData gameData();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/IndexData.java b/src/main/java/org/hedgecode/chess/scanner/format/IndexData.java
new file mode 100644 (file)
index 0000000..0841aa7
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * IndexData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface IndexData {
+
+    Room[] rooms();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/Move.java b/src/main/java/org/hedgecode/chess/scanner/format/Move.java
new file mode 100644 (file)
index 0000000..8b9a02e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * Move
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Move {
+
+    int number();
+
+    String move();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/Player.java b/src/main/java/org/hedgecode/chess/scanner/format/Player.java
new file mode 100644 (file)
index 0000000..17b009d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * Player
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Player {
+
+    int id();
+
+    String name();
+
+    String firstName();
+
+    String lastName();
+
+    int fideId();
+
+    int elo();
+
+    String title();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/Room.java b/src/main/java/org/hedgecode/chess/scanner/format/Room.java
new file mode 100644 (file)
index 0000000..1303f01
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+import java.util.Date;
+
+/**
+ * Room
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface Room {
+
+    int id();
+
+    int indexId();
+
+    String slug();
+
+    String name();
+
+    String shortName();
+
+    int weight();
+
+    Date startAt();
+
+    Date endAt();
+
+    Date updateAt();
+
+    String eventType();
+
+    String scoring();
+
+    String officialUrl();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/RoomData.java b/src/main/java/org/hedgecode/chess/scanner/format/RoomData.java
new file mode 100644 (file)
index 0000000..8c160b9
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+/**
+ * RoomData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface RoomData {
+
+    Room room();
+
+    Game[] games();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/format/TournamentFormat.java b/src/main/java/org/hedgecode/chess/scanner/format/TournamentFormat.java
new file mode 100644 (file)
index 0000000..5e6d9b6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.format;
+
+import java.util.List;
+
+/**
+ * TournamentFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface TournamentFormat extends BaseFormat {
+
+    String id();
+
+    String name();
+
+    RoomData roomData();
+
+    List<String> gameUrls();
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/AbstractBaseFormat.java b/src/main/java/org/hedgecode/chess/scanner/json/format/AbstractBaseFormat.java
new file mode 100644 (file)
index 0000000..09c6b0f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.BaseFormat;
+
+/**
+ * AbstractBaseFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public abstract class AbstractBaseFormat implements BaseFormat {
+
+    @SerializedName("baseUrl")
+    private String baseUrl;
+
+    @SerializedName("arenaPath")
+    private String arenaPath;
+
+    @Override
+    public String baseUrl() {
+        return baseUrl;
+    }
+
+    @Override
+    public String arenaPath() {
+        return arenaPath;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/AbstractPGNFormat.java b/src/main/java/org/hedgecode/chess/scanner/json/format/AbstractPGNFormat.java
new file mode 100644 (file)
index 0000000..97b5ff2
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hedgecode.chess.scanner.ChessHogScannerConstants;
+import org.hedgecode.chess.scanner.entity.PGNEntity;
+import org.hedgecode.chess.scanner.entity.PGNTag;
+
+/**
+ * AbstractPGNFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public abstract class AbstractPGNFormat extends AbstractBaseFormat implements PGNEntity {
+
+    private static final String EMPTY = "";
+
+    private static final String MOVES_FORMAT = "%s %s";
+
+    private final Map<PGNTag, String> pgnTags = new HashMap<>();
+    private String pgnMoves;
+
+    protected abstract void assignPGN();
+
+    protected void addTag(PGNTag tag, String value) {
+        pgnTags.put(tag, value);
+    }
+
+    protected void addMoves(String moves) {
+        pgnMoves = moves;
+    }
+
+    private String moves() {
+        return pgnMoves != null ? pgnMoves : EMPTY;
+    }
+
+    private String result() {
+        String result = pgnTags.get(PGNTag.RESULT);
+        return result != null ? result : PGNTag.RESULT.defaultValue();
+    }
+
+    @Override
+    public String pgn() {
+        assignPGN();
+        StringBuilder sb = new StringBuilder();
+        for (PGNTag tag : PGNTag.values()) {
+            String tagValue = pgnTags.get(tag);
+            if (tag.isRequired() || tagValue != null) {
+                sb.append(
+                        String.format(
+                                PGNTag.TAG_FORMAT,
+                                tag.getName(),
+                                tagValue != null ? tagValue : tag.defaultValue()
+                        )
+                ).append(
+                        ChessHogScannerConstants.CRLF
+                );
+            }
+        }
+        sb.append(
+                ChessHogScannerConstants.CRLF
+        ).append(
+                String.format(MOVES_FORMAT, moves(), result())
+        ).append(
+                ChessHogScannerConstants.CRLF
+        );
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONArenaFormat.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONArenaFormat.java
new file mode 100644 (file)
index 0000000..5964f71
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.ArenaFormat;
+import org.hedgecode.chess.scanner.format.IndexData;
+import org.hedgecode.chess.scanner.format.Room;
+
+/**
+ * JSONArenaFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONArenaFormat extends AbstractBaseFormat implements ArenaFormat {
+
+    @SerializedName("indexData")
+    private JSONIndexData indexData;
+
+    JSONArenaFormat() {
+    }
+
+    @Override
+    public IndexData indexData() {
+        return indexData;
+    }
+
+    @Override
+    public String findTournament(String tournamentName) {
+        for (Room room : indexData.rooms()) {
+            if (room.name().contains(tournamentName)) {
+                return room.slug();
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONFormatBuilder.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONFormatBuilder.java
new file mode 100644 (file)
index 0000000..bdc63ff
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import org.hedgecode.chess.scanner.format.ArenaFormat;
+import org.hedgecode.chess.scanner.format.FormatBuilder;
+import org.hedgecode.chess.scanner.format.GameFormat;
+import org.hedgecode.chess.scanner.format.TournamentFormat;
+
+/**
+ * JSONFormatBuilder
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONFormatBuilder implements FormatBuilder {
+
+    private static final Gson GSON = new GsonBuilder().create();
+
+    @Override
+    public GameFormat buildGame(String jsonGame) {
+        return GSON.fromJson(
+                jsonGame,
+                JSONGameFormat.class
+            );
+    }
+
+    @Override
+    public TournamentFormat buildTournament(String jsonTournament) {
+        return GSON.fromJson(
+                jsonTournament,
+                JSONTournamentFormat.class
+        );
+    }
+
+    @Override
+    public ArenaFormat buildArena(String jsonArena) {
+        return GSON.fromJson(
+                jsonArena,
+                JSONArenaFormat.class
+        );
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGame.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGame.java
new file mode 100644 (file)
index 0000000..4575fe3
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import java.util.Date;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Game;
+import org.hedgecode.chess.scanner.format.Player;
+
+/**
+ * JSONGame
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONGame implements Game {
+
+    @SerializedName("id")
+    private int id;
+
+    @SerializedName("roomId")
+    private int roomId;
+
+    @SerializedName("slug")
+    private String slug;
+
+    @SerializedName("roundSlug")
+    private String roundSlug;
+
+    @SerializedName("whiteId")
+    private int whiteId;
+
+    @SerializedName("blackId")
+    private int blackId;
+
+    @SerializedName("whiteElo")
+    private int whiteElo;
+
+    @SerializedName("blackElo")
+    private int blackElo;
+
+    @SerializedName("startAt")
+    private Date startAt;
+
+    @SerializedName("endAt")
+    private Date endAt;
+
+    @SerializedName("updateAt")
+    private Date updateAt;
+
+    @SerializedName("result")
+    private String result;
+
+    @SerializedName("table")
+    private int table;
+
+    @SerializedName("board")
+    private int board;
+
+    @SerializedName("white")
+    private JSONPlayer white;
+
+    @SerializedName("black")
+    private JSONPlayer black;
+
+    JSONGame() {
+    }
+
+    @Override
+    public int id() {
+        return id;
+    }
+
+    @Override
+    public int roomId() {
+        return roomId;
+    }
+
+    @Override
+    public String slug() {
+        return slug;
+    }
+
+    @Override
+    public String roundSlug() {
+        return roundSlug;
+    }
+
+    @Override
+    public int whiteId() {
+        return whiteId;
+    }
+
+    @Override
+    public int blackId() {
+        return blackId;
+    }
+
+    @Override
+    public int whiteElo() {
+        return whiteElo;
+    }
+
+    @Override
+    public int blackElo() {
+        return blackElo;
+    }
+
+    @Override
+    public Date startAt() {
+        return startAt;
+    }
+
+    @Override
+    public Date endAt() {
+        return endAt;
+    }
+
+    @Override
+    public Date updateAt() {
+        return updateAt;
+    }
+
+    @Override
+    public String result() {
+        return result;
+    }
+
+    @Override
+    public int table() {
+        return table;
+    }
+
+    @Override
+    public int board() {
+        return board;
+    }
+
+    @Override
+    public Player white() {
+        return white;
+    }
+
+    @Override
+    public Player black() {
+        return black;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameData.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameData.java
new file mode 100644 (file)
index 0000000..9761b01
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Game;
+import org.hedgecode.chess.scanner.format.GameData;
+import org.hedgecode.chess.scanner.format.Move;
+import org.hedgecode.chess.scanner.format.Room;
+
+/**
+ * JSONGameData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONGameData implements GameData {
+
+    private static final String WHITE_MOVE_FORMAT = "%d. %s ";
+    private static final String BLACK_MOVE_FORMAT = "%s ";
+
+    @SerializedName("game")
+    private JSONGame game;
+
+    @SerializedName("room")
+    private JSONRoom room;
+
+    @SerializedName("moves")
+    private JSONMove[] moves;
+
+    JSONGameData() {
+    }
+
+    @Override
+    public Game game() {
+        return game;
+    }
+
+    @Override
+    public Room room() {
+        return room;
+    }
+
+    @Override
+    public Move[] moves() {
+        return moves;
+    }
+
+    @Override
+    public String formatMoves() {
+        StringBuilder sb = new StringBuilder();
+        for (Move move : moves) {
+            if (move.number() % 2 == 0) {
+                sb.append(
+                        String.format(WHITE_MOVE_FORMAT, move.number() / 2 + 1, move.move())
+                );
+            } else {
+                sb.append(
+                        String.format(BLACK_MOVE_FORMAT, move.move())
+                );
+            }
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameFormat.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONGameFormat.java
new file mode 100644 (file)
index 0000000..d4eb023
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.entity.PGNTag;
+import org.hedgecode.chess.scanner.format.GameData;
+import org.hedgecode.chess.scanner.format.GameFormat;
+
+/**
+ * JSONGameFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONGameFormat extends AbstractPGNFormat implements GameFormat {
+
+    private final DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
+    private final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
+
+    @SerializedName("gameData")
+    private JSONGameData gameData;
+
+    JSONGameFormat() {
+    }
+
+    @Override
+    public String id() {
+        return Integer.toString(
+                gameData().game().id()
+        );
+    }
+
+    @Override
+    public GameData gameData() {
+        return gameData;
+    }
+
+    @Override
+    protected void assignPGN() {
+        addTag(PGNTag.EVENT, gameData.room().name());
+        addTag(PGNTag.DATE, dateFormat.format(gameData.game().startAt()));
+        addTag(PGNTag.ROUND, gameData.game().roundSlug());
+        addTag(PGNTag.WHITE, gameData.game().white().name());
+        addTag(PGNTag.BLACK, gameData.game().black().name());
+        addTag(PGNTag.WHITE_TITLE, gameData.game().white().title());
+        addTag(PGNTag.BLACK_TITLE, gameData.game().black().title());
+        addTag(PGNTag.WHITE_ELO, Integer.toString(gameData.game().white().elo()));
+        addTag(PGNTag.BLACK_ELO, Integer.toString(gameData.game().black().elo()));
+        addTag(PGNTag.TIME, timeFormat.format(gameData.game().startAt()));
+        addTag(PGNTag.RESULT, gameData.game().result());
+
+        addMoves(gameData.formatMoves());
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONIndexData.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONIndexData.java
new file mode 100644 (file)
index 0000000..f5ad7e8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.IndexData;
+import org.hedgecode.chess.scanner.format.Room;
+
+/**
+ * JSONIndexData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONIndexData implements IndexData {
+
+    @SerializedName("rooms")
+    private JSONRoom[] rooms;
+
+    JSONIndexData() {
+    }
+
+    @Override
+    public Room[] rooms() {
+        return rooms;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONMove.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONMove.java
new file mode 100644 (file)
index 0000000..6a65e40
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Move;
+
+/**
+ * JSONMove
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONMove implements Move {
+
+    private static final char MOVE_DELIMITER = '_';
+
+    @SerializedName("ply")
+    private int ply;
+
+    @SerializedName("cbn")
+    private String cbn;
+
+    JSONMove() {
+    }
+
+    @Override
+    public int number() {
+        return ply;
+    }
+
+    @Override
+    public String move() {
+        return cbn.substring(
+                cbn.lastIndexOf(MOVE_DELIMITER) + 1
+        );
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONPlayer.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONPlayer.java
new file mode 100644 (file)
index 0000000..4fbfdff
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Player;
+
+/**
+ * JSONPlayer
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONPlayer implements Player {
+
+    @SerializedName("id")
+    private int id;
+
+    @SerializedName("name")
+    private String name;
+
+    @SerializedName("firstName")
+    private String firstName;
+
+    @SerializedName("lastName")
+    private String lastName;
+
+    @SerializedName("fideId")
+    private int fideId;
+
+    @SerializedName("elo")
+    private int elo;
+
+    @SerializedName("title")
+    private String title;
+
+    JSONPlayer() {
+    }
+
+    @Override
+    public int id() {
+        return id;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public String firstName() {
+        return firstName;
+    }
+
+    @Override
+    public String lastName() {
+        return lastName;
+    }
+
+    @Override
+    public int fideId() {
+        return fideId;
+    }
+
+    @Override
+    public int elo() {
+        return elo;
+    }
+
+    @Override
+    public String title() {
+        return title;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoom.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoom.java
new file mode 100644 (file)
index 0000000..767d2af
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import java.util.Date;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Room;
+
+/**
+ * JSONRoom
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONRoom implements Room {
+
+    @SerializedName("id")
+    private int id;
+
+    @SerializedName("indexId")
+    private int indexId;
+
+    @SerializedName("slug")
+    private String slug;
+
+    @SerializedName("name")
+    private String name;
+
+    @SerializedName("shortName")
+    private String shortName;
+
+    @SerializedName("weight")
+    private int weight;
+
+    @SerializedName("startAt")
+    private Date startAt;
+
+    @SerializedName("endAt")
+    private Date endAt;
+
+    @SerializedName("updateAt")
+    private Date updateAt;
+
+    @SerializedName("eventType")
+    private String eventType;
+
+    @SerializedName("scoring")
+    private String scoring;
+
+    @SerializedName("officialUrl")
+    private String officialUrl;
+
+    JSONRoom() {
+    }
+
+    @Override
+    public int id() {
+        return id;
+    }
+
+    @Override
+    public int indexId() {
+        return indexId;
+    }
+
+    @Override
+    public String slug() {
+        return slug;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public String shortName() {
+        return shortName;
+    }
+
+    @Override
+    public int weight() {
+        return weight;
+    }
+
+    @Override
+    public Date startAt() {
+        return startAt;
+    }
+
+    @Override
+    public Date endAt() {
+        return endAt;
+    }
+
+    @Override
+    public Date updateAt() {
+        return updateAt;
+    }
+
+    @Override
+    public String eventType() {
+        return eventType;
+    }
+
+    @Override
+    public String scoring() {
+        return scoring;
+    }
+
+    @Override
+    public String officialUrl() {
+        return officialUrl;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoomData.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONRoomData.java
new file mode 100644 (file)
index 0000000..c48af39
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Game;
+import org.hedgecode.chess.scanner.format.Room;
+import org.hedgecode.chess.scanner.format.RoomData;
+
+/**
+ * JSONRoomData
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONRoomData implements RoomData {
+
+    @SerializedName("room")
+    private JSONRoom room;
+
+    @SerializedName("games")
+    private JSONGame[] games;
+
+    JSONRoomData() {
+    }
+
+    @Override
+    public Room room() {
+        return room;
+    }
+
+    @Override
+    public Game[] games() {
+        return games;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/json/format/JSONTournamentFormat.java b/src/main/java/org/hedgecode/chess/scanner/json/format/JSONTournamentFormat.java
new file mode 100644 (file)
index 0000000..f568e09
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.hedgecode.chess.scanner.json.format;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.hedgecode.chess.scanner.format.Game;
+import org.hedgecode.chess.scanner.format.RoomData;
+import org.hedgecode.chess.scanner.format.TournamentFormat;
+
+/**
+ * JSONTournamentFormat
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class JSONTournamentFormat extends AbstractBaseFormat implements TournamentFormat {
+
+    private static final String GAME_URL_FORMAT = "%s-%s";
+
+    @SerializedName("roomData")
+    private JSONRoomData roomData;
+
+    JSONTournamentFormat() {
+    }
+
+    @Override
+    public String id() {
+        return Integer.toString(
+                roomData().room().id()
+        );
+    }
+
+    @Override
+    public String name() {
+        return roomData().room().name();
+    }
+
+    @Override
+    public RoomData roomData() {
+        return roomData;
+    }
+
+    @Override
+    public List<String> gameUrls() {
+        List<String> gameUrls = new ArrayList<>();
+        for (Game game : roomData.games()) {
+            gameUrls.add(
+                    String.format(GAME_URL_FORMAT, game.roundSlug(), game.slug())
+            );
+        }
+        return gameUrls;
+    }
+
+}