summaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/build.gradle50
-rw-r--r--api/src/main/java/mancala/App.java49
-rw-r--r--api/src/main/java/mancala/api/PlayMancala.java55
-rw-r--r--api/src/main/java/mancala/api/StartMancala.java33
-rw-r--r--api/src/main/java/mancala/api/models/GameStatus.java24
-rw-r--r--api/src/main/java/mancala/api/models/Mancala.java21
-rw-r--r--api/src/main/java/mancala/api/models/Pit.java18
-rw-r--r--api/src/main/java/mancala/api/models/PlayInfo.java17
-rw-r--r--api/src/main/java/mancala/api/models/Player.java28
-rw-r--r--api/src/main/java/mancala/api/models/PlayerInput.java23
-rw-r--r--api/src/test/java/mancala/api/StartMancalaTest.java96
11 files changed, 414 insertions, 0 deletions
diff --git a/api/build.gradle b/api/build.gradle
new file mode 100644
index 0000000..6dc681a
--- /dev/null
+++ b/api/build.gradle
@@ -0,0 +1,50 @@
+
+plugins {
+ id 'java'
+ // This time we're building a command-line executable application.
+ id 'application'
+}
+
+repositories {
+ jcenter()
+}
+
+dependencies {
+
+ // Use the Jersey framework to make writing and testing servlets easier.
+ implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:+'
+ implementation 'org.glassfish.jersey.containers:jersey-container-jetty-http:+'
+ implementation 'org.glassfish.jersey.core:jersey-server:+'
+ implementation 'org.glassfish.jersey.inject:jersey-hk2:+'
+ implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:+'
+ // Use Jakarta (Java EE) for the servlet primitives.
+ implementation 'jakarta.servlet:jakarta.servlet-api:+'
+ // Use the Jetty server.
+ implementation 'org.eclipse.jetty:jetty-server:+'
+ implementation 'org.eclipse.jetty:jetty-servlet:+'
+ implementation 'org.eclipse.jetty:jetty-webapp:+'
+ // We want to have some logging output if things go wrong, so use the simple console logger from SLF4J.
+ // In our simple use case, the logger gets automatically configured by simply existing.
+ implementation 'org.slf4j:slf4j-simple:+'
+
+ // Reference the domain subproject.
+ implementation project(':domain')
+
+ // Use JUnit Jupiter API for testing.
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
+ // Also use the Mockito mocking framework to mock simple server functionality.
+ testImplementation "org.mockito:mockito-core:2.+"
+
+ // Use JUnit Jupiter Engine for testing.
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
+}
+
+application {
+ // Define the main class for the application.
+ mainClassName = 'mancala.App'
+}
+
+test {
+ // Use junit platform for unit tests
+ useJUnitPlatform()
+}
diff --git a/api/src/main/java/mancala/App.java b/api/src/main/java/mancala/App.java
new file mode 100644
index 0000000..8560e2d
--- /dev/null
+++ b/api/src/main/java/mancala/App.java
@@ -0,0 +1,49 @@
+package mancala;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.*;
+import org.eclipse.jetty.webapp.*;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.glassfish.jersey.servlet.ServletContainer;
+
+import mancala.api.*;
+
+public class App {
+ public static void main(String[] args) throws Exception {
+ Server server = startServer(8080);
+ ServletContextHandler context = createStatefulContext(server);
+ registerServlets(context);
+
+ server.start();
+ System.out.println("Started server.");
+ System.out.println("Listening on http://localhost:8080/");
+ System.out.println("Press CTRL+C to exit.");
+ server.join();
+ }
+
+ private static Server startServer(int port) {
+ return new Server(8080);
+ }
+
+ private static ServletContextHandler createStatefulContext(Server server) {
+ ServletContextHandler context =
+ new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/");
+ server.setHandler(context);
+ return context;
+ }
+
+ private static void registerServlets(ServletContextHandler context) {
+ // Use the Jersey framework to translate the classes in the
+ // mancala.api package to server endpoints (servlets).
+ // For example, the StartMancala class will become an endpoint at
+ // http://localost:8080/mancala/api/start
+ ServletHolder serverHolder = context.addServlet(ServletContainer.class, "/mancala/api/*");
+ serverHolder.setInitOrder(1);
+ serverHolder.setInitParameter("jersey.config.server.provider.packages",
+ "mancala.api");
+ }
+}
diff --git a/api/src/main/java/mancala/api/PlayMancala.java b/api/src/main/java/mancala/api/PlayMancala.java
new file mode 100644
index 0000000..3b59710
--- /dev/null
+++ b/api/src/main/java/mancala/api/PlayMancala.java
@@ -0,0 +1,55 @@
+package mancala.api;
+
+import java.io.IOException;
+import jakarta.servlet.http.*;
+import jakarta.servlet.ServletException;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.*;
+
+import mancala.api.models.*;
+import mancala.domain.MancalaException;
+import mancala.domain.MancalaImpl;
+
+// public class StartMancala {
+// @POST
+// @Consumes(MediaType.APPLICATION_JSON)
+// @Produces(MediaType.APPLICATION_JSON)
+// public Response initialize(
+// @Context HttpServletRequest request,
+// PlayerInput players) {
+// // var mancala = new MancalaImpl();
+// var mancala = new MancalaImpl(new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13});
+// String namePlayer1 = players.getNameplayer1();
+// String namePlayer2 = players.getNameplayer2();
+//
+// HttpSession session = request.getSession(true);
+// session.setAttribute("mancala", mancala);
+// session.setAttribute("player1", namePlayer1);
+// session.setAttribute("player2", namePlayer2);
+//
+// var output = new Mancala(mancala, namePlayer1, namePlayer2);
+// return Response.status(200).entity(output).build();
+// }
+// }
+@Path("/play")
+public class PlayMancala {
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response initialize(@Context HttpServletRequest request, PlayInfo playInfo) {
+
+ HttpSession session = request.getSession();
+
+ MancalaImpl mancala = (MancalaImpl) session.getAttribute("mancala");
+ String namePlayer1 = (String) session.getAttribute("player1");
+ String namePlayer2 = (String) session.getAttribute("player2");
+ try {
+ mancala.playPit(playInfo.getIndex());
+ } catch (MancalaException e) {
+ return Response.status(403).build();
+ }
+ var output = new Mancala(mancala, namePlayer1, namePlayer2);
+
+ return Response.status(200).entity(output).build();
+ }
+}
diff --git a/api/src/main/java/mancala/api/StartMancala.java b/api/src/main/java/mancala/api/StartMancala.java
new file mode 100644
index 0000000..62339d7
--- /dev/null
+++ b/api/src/main/java/mancala/api/StartMancala.java
@@ -0,0 +1,33 @@
+package mancala.api;
+
+import java.io.IOException;
+import jakarta.servlet.http.*;
+import jakarta.servlet.ServletException;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.*;
+
+import mancala.api.models.*;
+import mancala.domain.MancalaImpl;
+
+@Path("/start")
+public class StartMancala {
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response initialize(
+ @Context HttpServletRequest request,
+ PlayerInput players) {
+ var mancala = new MancalaImpl();
+ // var mancala = new MancalaImpl(new int[] {40,40,40,40,40,40,40,40,40,40,40,40,40,40});
+ String namePlayer1 = players.getNameplayer1();
+ String namePlayer2 = players.getNameplayer2();
+
+ HttpSession session = request.getSession(true);
+ session.setAttribute("mancala", mancala);
+ session.setAttribute("player1", namePlayer1);
+ session.setAttribute("player2", namePlayer2);
+
+ var output = new Mancala(mancala, namePlayer1, namePlayer2);
+ return Response.status(200).entity(output).build();
+ }
+}
diff --git a/api/src/main/java/mancala/api/models/GameStatus.java b/api/src/main/java/mancala/api/models/GameStatus.java
new file mode 100644
index 0000000..a90269c
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/GameStatus.java
@@ -0,0 +1,24 @@
+package mancala.api.models;
+
+public class GameStatus {
+ boolean endOfGame;
+ public boolean getEndOfGame() { return endOfGame; }
+
+ String winner;
+ public String getWinner() { return winner; }
+
+ public GameStatus(mancala.domain.Mancala mancala,
+ String namePlayer1, String namePlayer2) {
+ this.endOfGame = mancala.isEndOfGame();
+ int winner = mancala.getWinner();
+ if(winner == mancala.NO_PLAYERS) {
+ this.winner = null;
+ } else if(winner == mancala.PLAYER_ONE) {
+ this.winner = namePlayer1;
+ } else if(winner == mancala.PLAYER_TWO) {
+ this.winner = namePlayer2;
+ } else {
+ this.winner = namePlayer1 + "and" + namePlayer2;
+ }
+ }
+} \ No newline at end of file
diff --git a/api/src/main/java/mancala/api/models/Mancala.java b/api/src/main/java/mancala/api/models/Mancala.java
new file mode 100644
index 0000000..bb747c5
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/Mancala.java
@@ -0,0 +1,21 @@
+package mancala.api.models;
+
+// This package is a collection of DTO's (data transfer objects).
+// A DTO is a simple datastructure which models the
+// data your web API sends back to the client. The Java
+// objects will be converted to JSON objects.
+public class Mancala {
+ public Mancala(mancala.domain.Mancala mancala,
+ String namePlayer1, String namePlayer2) {
+ players = new Player[2];
+ players[0] = new Player(mancala, namePlayer1, true);
+ players[1] = new Player(mancala, namePlayer2, false);
+ gameStatus = new GameStatus(mancala, namePlayer1, namePlayer2);
+ }
+
+ Player[] players;
+ public Player[] getPlayers() { return players; }
+
+ GameStatus gameStatus;
+ public GameStatus getGameStatus() { return gameStatus; }
+} \ No newline at end of file
diff --git a/api/src/main/java/mancala/api/models/Pit.java b/api/src/main/java/mancala/api/models/Pit.java
new file mode 100644
index 0000000..457d19b
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/Pit.java
@@ -0,0 +1,18 @@
+package mancala.api.models;
+
+public class Pit {
+ int index;
+
+ public int getIndex() {
+ return index;
+ }
+
+ int nrOfStones;
+
+ public int getNrOfStones() { return nrOfStones; }
+
+ public Pit(int index, int nrOfStones) {
+ this.index = index;
+ this.nrOfStones = nrOfStones;
+ }
+} \ No newline at end of file
diff --git a/api/src/main/java/mancala/api/models/PlayInfo.java b/api/src/main/java/mancala/api/models/PlayInfo.java
new file mode 100644
index 0000000..9caca4d
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/PlayInfo.java
@@ -0,0 +1,17 @@
+package mancala.api.models;
+
+public class PlayInfo {
+ int player;
+ int index;
+
+
+
+ public void setPlayer(int player) {this.player = player;}
+ public int getPlayer() {return player;}
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+ public int getIndex() {return index;}
+
+}
diff --git a/api/src/main/java/mancala/api/models/Player.java b/api/src/main/java/mancala/api/models/Player.java
new file mode 100644
index 0000000..f987e82
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/Player.java
@@ -0,0 +1,28 @@
+package mancala.api.models;
+
+public class Player {
+ public Player(mancala.domain.Mancala mancala,
+ String name, boolean isFirstPlayer) {
+ this.name = name;
+ type = isFirstPlayer ? "player1" : "player2";
+ hasTurn = mancala.isPlayersTurn(isFirstPlayer ?
+ mancala.PLAYER_ONE : mancala.PLAYER_TWO);
+ this.pits = new Pit[7];
+ var firstHole = isFirstPlayer ? 0 : 7;
+ for(int i = 0; i < 7; ++i) {
+ this.pits[i] = new Pit(i + firstHole, mancala.getStonesForPit(i + firstHole));
+ }
+ }
+
+ String name;
+ public String getName() { return name; }
+
+ String type;
+ public String getType() { return type; }
+
+ boolean hasTurn;
+ public boolean getHasTurn() { return hasTurn; }
+
+ Pit[] pits;
+ public Pit[] getPits() { return pits; }
+} \ No newline at end of file
diff --git a/api/src/main/java/mancala/api/models/PlayerInput.java b/api/src/main/java/mancala/api/models/PlayerInput.java
new file mode 100644
index 0000000..8fdbd2a
--- /dev/null
+++ b/api/src/main/java/mancala/api/models/PlayerInput.java
@@ -0,0 +1,23 @@
+package mancala.api.models;
+
+public class PlayerInput {
+
+ String nameplayer1;
+ String nameplayer2;
+
+ public String getNameplayer1() {
+ return nameplayer1;
+ }
+
+ public void setNameplayer1(String nameplayer1) {
+ this.nameplayer1 = nameplayer1;
+ }
+
+ public String getNameplayer2() {
+ return nameplayer2;
+ }
+
+ public void setNameplayer2(String nameplayer2) {
+ this.nameplayer2 = nameplayer2;
+ }
+} \ No newline at end of file
diff --git a/api/src/test/java/mancala/api/StartMancalaTest.java b/api/src/test/java/mancala/api/StartMancalaTest.java
new file mode 100644
index 0000000..0c4b23f
--- /dev/null
+++ b/api/src/test/java/mancala/api/StartMancalaTest.java
@@ -0,0 +1,96 @@
+package mancala.api;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import jakarta.servlet.http.*;
+import jakarta.ws.rs.core.*;
+
+import mancala.api.models.*;
+import mancala.domain.MancalaImpl;
+
+public class StartMancalaTest {
+ @Test
+ public void startingMancalaShouldBeAllowed() {
+ var response = startMancala("Mario", "Luigi");
+ assertEquals(200, response.getStatus());
+ }
+
+ @Test
+ public void startingMancalaReturnsAGameWithoutAWinner() {
+ var response = startMancala("Mario", "Luigi");
+ var entity = (Mancala)response.getEntity();
+ var gameState = entity.getGameStatus();
+ assertFalse(gameState.getEndOfGame());
+ assertNull(gameState.getWinner());
+ }
+
+ @Test
+ public void startingMancalaReturnsThePlayerData() {
+ var response = startMancala("Mario", "Luigi");
+ var entity = (Mancala)response.getEntity();
+ var players = entity.getPlayers();
+ assertEquals(2, players.length);
+ assertEquals("Mario", players[0].getName());
+ assertEquals("Luigi", players[1].getName());
+ }
+
+ @Test
+ public void startingMancalaReturnsThePits() {
+ var response = startMancala("Mario", "Luigi");
+ var entity = (Mancala)response.getEntity();
+ var players = entity.getPlayers();
+ assertEquals(7, players[0].getPits().length);
+ assertEquals(0, players[0].getPits()[0].getIndex());
+ assertEquals(4, players[0].getPits()[0].getNrOfStones());
+ assertEquals(0, players[0].getPits()[6].getNrOfStones());
+ assertEquals(7, players[1].getPits().length);
+ assertEquals(7, players[1].getPits()[0].getIndex());
+ assertEquals(4, players[1].getPits()[0].getNrOfStones());
+ assertEquals(0, players[1].getPits()[6].getNrOfStones());
+ }
+
+ @Test
+ public void startingMancalaStartsANewSession() {
+ startMancala("Mario", "Luigi");
+ verify(request).getSession(true);
+ }
+
+ @Test
+ public void startingMancalaSavesTheNewGameInASession() {
+ startMancala("Mario", "Luigi");
+ verify(session).setAttribute(eq("mancala"), any(MancalaImpl.class));
+ }
+
+ @Test
+ public void startingMancalaSavesTheNamesInASession() {
+ startMancala("Mario", "Luigi");
+ verify(session).setAttribute("player1", "Mario");
+ verify(session).setAttribute("player2", "Luigi");
+ }
+
+ private Response startMancala(String namePlayer1, String namePlayer2) {
+ var servlet = new StartMancala();
+ var request = createRequestContext();
+ var input = playerInput(namePlayer1, namePlayer2);
+ return servlet.initialize(request, input);
+ }
+
+ private HttpServletRequest createRequestContext() {
+ request = mock(HttpServletRequest.class);
+ session = mock(HttpSession.class);
+ when(request.getSession(true)).thenReturn(session);
+ return request;
+ }
+
+ private HttpServletRequest request;
+ private HttpSession session;
+
+ private PlayerInput playerInput(String namePlayer1, String namePlayer2) {
+ var input = new PlayerInput();
+ input.setNameplayer1(namePlayer1);
+ input.setNameplayer2(namePlayer2);
+ return input;
+ }
+} \ No newline at end of file