提交 cd2a2e77 编写于 作者: A Anurag Agarwal 提交者: Ilkka Seppälä

Java 11 migrate all remaining s (#1120)

* Moves saga to Java 11

* Moves semaphore to Java 11

* Moves servant to Java 11

* Moves serverless to Java 11

* Moves service-layer to Java 11

* Moves service-locator to Java 11

* Moves sharding to Java 11

* Moves singleton to Java 11

* Moves spatial-partition to Java 11

* Moves specification to Java 11

* Moves state to Java 11

* Moves step-builder to Java 11

* Moves strategy to Java 11

* Moves subclass-sandbox to Java 11

* Fixes checkstyle issues
上级 310ae502
...@@ -25,9 +25,9 @@ package com.iluwatar.saga.choreography; ...@@ -25,9 +25,9 @@ package com.iluwatar.saga.choreography;
/** /**
* ChoreographyChapter is an interface representing a contract for an external service. * ChoreographyChapter is an interface representing a contract for an external service. In that
* In that case, a service needs to make a decision what to do further * case, a service needs to make a decision what to do further hence the server needs to get all
* hence the server needs to get all context representing {@link Saga} * context representing {@link Saga}
*/ */
public interface ChoreographyChapter { public interface ChoreographyChapter {
...@@ -41,6 +41,7 @@ public interface ChoreographyChapter { ...@@ -41,6 +41,7 @@ public interface ChoreographyChapter {
/** /**
* get name method. * get name method.
*
* @return service name. * @return service name.
*/ */
String getName(); String getName();
......
...@@ -28,9 +28,8 @@ import java.util.Arrays; ...@@ -28,9 +28,8 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* Saga representation. * Saga representation. Saga consists of chapters. Every ChoreographyChapter is executed a certain
* Saga consists of chapters. * service.
* Every ChoreographyChapter is executed a certain service.
*/ */
public class Saga { public class Saga {
...@@ -61,6 +60,7 @@ public class Saga { ...@@ -61,6 +60,7 @@ public class Saga {
/** /**
* add chapter to saga. * add chapter to saga.
*
* @param name chapter name * @param name chapter name
* @return this * @return this
*/ */
...@@ -71,6 +71,7 @@ public class Saga { ...@@ -71,6 +71,7 @@ public class Saga {
/** /**
* set value to last chapter. * set value to last chapter.
*
* @param value invalue * @param value invalue
* @return this * @return this
*/ */
...@@ -84,6 +85,7 @@ public class Saga { ...@@ -84,6 +85,7 @@ public class Saga {
/** /**
* get value from current chapter. * get value from current chapter.
*
* @return value * @return value
*/ */
public Object getCurrentValue() { public Object getCurrentValue() {
...@@ -92,6 +94,7 @@ public class Saga { ...@@ -92,6 +94,7 @@ public class Saga {
/** /**
* set value to current chapter. * set value to current chapter.
*
* @param value to set * @param value to set
*/ */
public void setCurrentValue(Object value) { public void setCurrentValue(Object value) {
...@@ -100,6 +103,7 @@ public class Saga { ...@@ -100,6 +103,7 @@ public class Saga {
/** /**
* set status for current chapter. * set status for current chapter.
*
* @param result to set * @param result to set
*/ */
public void setCurrentStatus(ChapterResult result) { public void setCurrentStatus(ChapterResult result) {
...@@ -145,8 +149,8 @@ public class Saga { ...@@ -145,8 +149,8 @@ public class Saga {
} }
/** /**
* Class presents a chapter status and incoming * Class presents a chapter status and incoming parameters(incoming parameter transforms to
* parameters(incoming parameter transforms to outcoming parameter). * outcoming parameter).
*/ */
public static class Chapter { public static class Chapter {
private String name; private String name;
...@@ -173,6 +177,7 @@ public class Saga { ...@@ -173,6 +177,7 @@ public class Saga {
/** /**
* set result. * set result.
*
* @param result {@link ChapterResult} * @param result {@link ChapterResult}
*/ */
public void setResult(ChapterResult result) { public void setResult(ChapterResult result) {
...@@ -181,6 +186,7 @@ public class Saga { ...@@ -181,6 +186,7 @@ public class Saga {
/** /**
* the result for chapter is good. * the result for chapter is good.
*
* @return true if is good otherwise bad * @return true if is good otherwise bad
*/ */
public boolean isSuccess() { public boolean isSuccess() {
......
...@@ -27,22 +27,19 @@ import org.slf4j.Logger; ...@@ -27,22 +27,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* This pattern is used in distributed services to perform a group of operations atomically. * This pattern is used in distributed services to perform a group of operations atomically. This is
* This is an analog of transaction in a database but in terms * an analog of transaction in a database but in terms of microservices architecture this is
* of microservices architecture this is executed * executed in a distributed environment
* in a distributed environment
* *
* <p>A saga is a sequence of local transactions in a certain context. * <p>A saga is a sequence of local transactions in a certain context.
* If one transaction fails for some reason, * If one transaction fails for some reason, the saga executes compensating transactions(rollbacks)
* the saga executes compensating transactions(rollbacks)
* to undo the impact of the preceding transactions. * to undo the impact of the preceding transactions.
* *
* <p>In this approach, there are no mediators or orchestrators services. * <p>In this approach, there are no mediators or orchestrators services.
* All chapters are handled and moved by services manually. * All chapters are handled and moved by services manually.
* *
* <p>The major difference with choreography saga is an ability to handle crashed services * <p>The major difference with choreography saga is an ability to handle crashed services
* (otherwise in choreography services very hard to prevent a saga * (otherwise in choreography services very hard to prevent a saga if one of them has been crashed)
* if one of them has been crashed)
* *
* @see com.iluwatar.saga.choreography.Saga * @see com.iluwatar.saga.choreography.Saga
* @see Service * @see Service
...@@ -54,10 +51,10 @@ public class SagaApplication { ...@@ -54,10 +51,10 @@ public class SagaApplication {
* main method. * main method.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
ServiceDiscoveryService sd = serviceDiscovery(); var sd = serviceDiscovery();
ChoreographyChapter service = sd.findAny(); var service = sd.findAny();
Saga goodOrderSaga = service.execute(newSaga("good_order")); var goodOrderSaga = service.execute(newSaga("good_order"));
Saga badOrderSaga = service.execute(newSaga("bad_order")); var badOrderSaga = service.execute(newSaga("bad_order"));
LOGGER.info("orders: goodOrder is {}, badOrder is {}", LOGGER.info("orders: goodOrder is {}, badOrder is {}",
goodOrderSaga.getResult(), badOrderSaga.getResult()); goodOrderSaga.getResult(), badOrderSaga.getResult());
...@@ -74,7 +71,7 @@ public class SagaApplication { ...@@ -74,7 +71,7 @@ public class SagaApplication {
} }
private static ServiceDiscoveryService serviceDiscovery() { private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService(); var sd = new ServiceDiscoveryService();
return sd return sd
.discover(new OrderService(sd)) .discover(new OrderService(sd))
.discover(new FlyBookingService(sd)) .discover(new FlyBookingService(sd))
......
...@@ -29,8 +29,8 @@ import org.slf4j.LoggerFactory; ...@@ -29,8 +29,8 @@ import org.slf4j.LoggerFactory;
/** /**
* Common abstraction class representing services. * Common abstraction class representing services. implementing a general contract @see {@link
* implementing a general contract @see {@link ChoreographyChapter} * ChoreographyChapter}
*/ */
public abstract class Service implements ChoreographyChapter { public abstract class Service implements ChoreographyChapter {
protected static final Logger LOGGER = LoggerFactory.getLogger(Service.class); protected static final Logger LOGGER = LoggerFactory.getLogger(Service.class);
...@@ -43,9 +43,9 @@ public abstract class Service implements ChoreographyChapter { ...@@ -43,9 +43,9 @@ public abstract class Service implements ChoreographyChapter {
@Override @Override
public Saga execute(Saga saga) { public Saga execute(Saga saga) {
Saga nextSaga = saga; var nextSaga = saga;
Object nextVal; Object nextVal;
String chapterName = saga.getCurrent().getName(); var chapterName = saga.getCurrent().getName();
if (chapterName.equals(getName())) { if (chapterName.equals(getName())) {
if (saga.isForward()) { if (saga.isForward()) {
nextSaga = process(saga); nextSaga = process(saga);
...@@ -67,7 +67,7 @@ public abstract class Service implements ChoreographyChapter { ...@@ -67,7 +67,7 @@ public abstract class Service implements ChoreographyChapter {
nextSaga.setCurrentValue(nextVal); nextSaga.setCurrentValue(nextVal);
} }
Saga finalNextSaga = nextSaga; var finalNextSaga = nextSaga;
return sd.find(chapterName).map(ch -> ch.execute(finalNextSaga)) return sd.find(chapterName).map(ch -> ch.execute(finalNextSaga))
.orElseThrow(serviceNotFoundException(chapterName)); .orElseThrow(serviceNotFoundException(chapterName));
...@@ -80,7 +80,7 @@ public abstract class Service implements ChoreographyChapter { ...@@ -80,7 +80,7 @@ public abstract class Service implements ChoreographyChapter {
@Override @Override
public Saga process(Saga saga) { public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue(); var inValue = saga.getCurrentValue();
LOGGER.info("The chapter '{}' has been started. " LOGGER.info("The chapter '{}' has been started. "
+ "The data {} has been stored or calculated successfully", + "The data {} has been stored or calculated successfully",
getName(), inValue); getName(), inValue);
...@@ -91,7 +91,7 @@ public abstract class Service implements ChoreographyChapter { ...@@ -91,7 +91,7 @@ public abstract class Service implements ChoreographyChapter {
@Override @Override
public Saga rollback(Saga saga) { public Saga rollback(Saga saga) {
Object inValue = saga.getCurrentValue(); var inValue = saga.getCurrentValue();
LOGGER.info("The Rollback for a chapter '{}' has been started. " LOGGER.info("The Rollback for a chapter '{}' has been started. "
+ "The data {} has been rollbacked successfully", + "The data {} has been rollbacked successfully",
getName(), inValue); getName(), inValue);
......
...@@ -39,7 +39,7 @@ public class WithdrawMoneyService extends Service { ...@@ -39,7 +39,7 @@ public class WithdrawMoneyService extends Service {
@Override @Override
public Saga process(Saga saga) { public Saga process(Saga saga) {
Object inValue = saga.getCurrentValue(); var inValue = saga.getCurrentValue();
if (inValue.equals("bad_order")) { if (inValue.equals("bad_order")) {
LOGGER.info("The chapter '{}' has been started. But the exception has been raised." LOGGER.info("The chapter '{}' has been started. But the exception has been raised."
......
...@@ -32,6 +32,7 @@ public interface OrchestrationChapter<K> { ...@@ -32,6 +32,7 @@ public interface OrchestrationChapter<K> {
/** /**
* method get name. * method get name.
*
* @return service name. * @return service name.
*/ */
String getName(); String getName();
......
...@@ -27,9 +27,8 @@ import java.util.ArrayList; ...@@ -27,9 +27,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Saga representation. * Saga representation. Saga consists of chapters. Every ChoreographyChapter is executed by a
* Saga consists of chapters. * certain service.
* Every ChoreographyChapter is executed by a certain service.
*/ */
public class Saga { public class Saga {
......
...@@ -27,23 +27,19 @@ import org.slf4j.Logger; ...@@ -27,23 +27,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* This pattern is used in distributed services to perform * This pattern is used in distributed services to perform a group of operations atomically. This is
* a group of operations atomically. * an analog of transaction in a database but in terms of microservices architecture this is
* This is an analog of transaction in a database but in terms * executed in a distributed environment
* of microservices architecture this is executed
* in a distributed environment
* *
* <p>A saga is a sequence of local transactions in a certain context. * <p>A saga is a sequence of local transactions in a certain context.
* If one transaction fails for some reason, * If one transaction fails for some reason, the saga executes compensating transactions(rollbacks)
* the saga executes compensating transactions(rollbacks)
* to undo the impact of the preceding transactions. * to undo the impact of the preceding transactions.
* *
* <p>In this approach, there is an orchestrator @see {@link SagaOrchestrator} * <p>In this approach, there is an orchestrator @see {@link SagaOrchestrator}
* that manages all the transactions and directs * that manages all the transactions and directs the participant services to execute local
* the participant services to execute local transactions based on events. * transactions based on events. The major difference with choreography saga is an ability to handle
* The major difference with choreography saga is an ability to handle crashed services * crashed services (otherwise in choreography services very hard to prevent a saga if one of them
* (otherwise in choreography services very hard to prevent a saga * has been crashed)
* if one of them has been crashed)
* *
* @see Saga * @see Saga
* @see SagaOrchestrator * @see SagaOrchestrator
...@@ -56,7 +52,7 @@ public class SagaApplication { ...@@ -56,7 +52,7 @@ public class SagaApplication {
* method to show common saga logic. * method to show common saga logic.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery()); var sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result goodOrder = sagaOrchestrator.execute("good_order"); Saga.Result goodOrder = sagaOrchestrator.execute("good_order");
Saga.Result badOrder = sagaOrchestrator.execute("bad_order"); Saga.Result badOrder = sagaOrchestrator.execute("bad_order");
...@@ -77,11 +73,10 @@ public class SagaApplication { ...@@ -77,11 +73,10 @@ public class SagaApplication {
} }
private static ServiceDiscoveryService serviceDiscovery() { private static ServiceDiscoveryService serviceDiscovery() {
return return new ServiceDiscoveryService()
new ServiceDiscoveryService() .discover(new OrderService())
.discover(new OrderService()) .discover(new FlyBookingService())
.discover(new FlyBookingService()) .discover(new HotelBookingService())
.discover(new HotelBookingService()) .discover(new WithdrawMoneyService());
.discover(new WithdrawMoneyService());
} }
} }
...@@ -23,18 +23,18 @@ ...@@ -23,18 +23,18 @@
package com.iluwatar.saga.orchestration; package com.iluwatar.saga.orchestration;
import static com.iluwatar.saga.orchestration.Saga.Result;
import static com.iluwatar.saga.orchestration.Saga.Result.CRASHED; import static com.iluwatar.saga.orchestration.Saga.Result.CRASHED;
import static com.iluwatar.saga.orchestration.Saga.Result.FINISHED; import static com.iluwatar.saga.orchestration.Saga.Result.FINISHED;
import static com.iluwatar.saga.orchestration.Saga.Result.ROLLBACK; import static com.iluwatar.saga.orchestration.Saga.Result.ROLLBACK;
import java.util.Optional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* The orchestrator that manages all the transactions and directs * The orchestrator that manages all the transactions and directs the participant services to
* the participant services to execute local transactions based on events. * execute local transactions based on events.
*/ */
public class SagaOrchestrator { public class SagaOrchestrator {
private static final Logger LOGGER = LoggerFactory.getLogger(SagaOrchestrator.class); private static final Logger LOGGER = LoggerFactory.getLogger(SagaOrchestrator.class);
...@@ -45,8 +45,9 @@ public class SagaOrchestrator { ...@@ -45,8 +45,9 @@ public class SagaOrchestrator {
/** /**
* Create a new service to orchetrate sagas. * Create a new service to orchetrate sagas.
*
* @param saga saga to process * @param saga saga to process
* @param sd service discovery @see {@link ServiceDiscoveryService} * @param sd service discovery @see {@link ServiceDiscoveryService}
*/ */
public SagaOrchestrator(Saga saga, ServiceDiscoveryService sd) { public SagaOrchestrator(Saga saga, ServiceDiscoveryService sd) {
this.saga = saga; this.saga = saga;
...@@ -59,30 +60,30 @@ public class SagaOrchestrator { ...@@ -59,30 +60,30 @@ public class SagaOrchestrator {
* *
* @param value incoming value * @param value incoming value
* @param <K> type for incoming value * @param <K> type for incoming value
* @return result @see {@link Saga.Result} * @return result @see {@link Result}
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <K> Saga.Result execute(K value) { public <K> Result execute(K value) {
state.cleanUp(); state.cleanUp();
LOGGER.info(" The new saga is about to start"); LOGGER.info(" The new saga is about to start");
Saga.Result result = FINISHED; var result = FINISHED;
K tempVal = value; K tempVal = value;
while (true) { while (true) {
int next = state.current(); var next = state.current();
Saga.Chapter ch = saga.get(next); var ch = saga.get(next);
Optional<OrchestrationChapter> srvOpt = sd.find(ch.name); var srvOpt = sd.find(ch.name);
if (!srvOpt.isPresent()) { if (srvOpt.isEmpty()) {
state.directionToBack(); state.directionToBack();
state.back(); state.back();
continue; continue;
} }
OrchestrationChapter srv = srvOpt.get(); var srv = srvOpt.get();
if (state.isForward()) { if (state.isForward()) {
ChapterResult processRes = srv.process(tempVal); var processRes = srv.process(tempVal);
if (processRes.isSuccess()) { if (processRes.isSuccess()) {
next = state.forward(); next = state.forward();
tempVal = (K) processRes.getValue(); tempVal = (K) processRes.getValue();
...@@ -90,7 +91,7 @@ public class SagaOrchestrator { ...@@ -90,7 +91,7 @@ public class SagaOrchestrator {
state.directionToBack(); state.directionToBack();
} }
} else { } else {
ChapterResult rlRes = srv.rollback(tempVal); var rlRes = srv.rollback(tempVal);
if (rlRes.isSuccess()) { if (rlRes.isSuccess()) {
next = state.back(); next = state.back();
tempVal = (K) rlRes.getValue(); tempVal = (K) rlRes.getValue();
......
...@@ -27,8 +27,8 @@ import org.slf4j.Logger; ...@@ -27,8 +27,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Common abstraction class representing services. * Common abstraction class representing services. implementing a general contract @see {@link
* implementing a general contract @see {@link OrchestrationChapter} * OrchestrationChapter}
* *
* @param <K> type of incoming param * @param <K> type of incoming param
*/ */
......
...@@ -33,10 +33,10 @@ public class SagaChoreographyTest { ...@@ -33,10 +33,10 @@ public class SagaChoreographyTest {
@Test @Test
public void executeTest() { public void executeTest() {
ServiceDiscoveryService sd = serviceDiscovery(); var sd = serviceDiscovery();
ChoreographyChapter service = sd.findAny(); var service = sd.findAny();
Saga badOrderSaga = service.execute(newSaga("bad_order")); var badOrderSaga = service.execute(newSaga("bad_order"));
Saga goodOrderSaga = service.execute(newSaga("good_order")); var goodOrderSaga = service.execute(newSaga("good_order"));
Assert.assertEquals(badOrderSaga.getResult(), Saga.SagaResult.ROLLBACKED); Assert.assertEquals(badOrderSaga.getResult(), Saga.SagaResult.ROLLBACKED);
Assert.assertEquals(goodOrderSaga.getResult(), Saga.SagaResult.FINISHED); Assert.assertEquals(goodOrderSaga.getResult(), Saga.SagaResult.FINISHED);
...@@ -52,7 +52,7 @@ public class SagaChoreographyTest { ...@@ -52,7 +52,7 @@ public class SagaChoreographyTest {
} }
private static ServiceDiscoveryService serviceDiscovery() { private static ServiceDiscoveryService serviceDiscovery() {
ServiceDiscoveryService sd = new ServiceDiscoveryService(); var sd = new ServiceDiscoveryService();
return sd return sd
.discover(new OrderService(sd)) .discover(new OrderService(sd))
.discover(new FlyBookingService(sd)) .discover(new FlyBookingService(sd))
......
...@@ -24,8 +24,6 @@ package com.iluwatar.saga.orchestration; ...@@ -24,8 +24,6 @@ package com.iluwatar.saga.orchestration;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
/** /**
* empty test * empty test
*/ */
......
...@@ -22,11 +22,12 @@ ...@@ -22,11 +22,12 @@
*/ */
package com.iluwatar.saga.orchestration; package com.iluwatar.saga.orchestration;
import org.junit.Assert; import static com.iluwatar.saga.orchestration.Saga.Result;
import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/** /**
* test to test orchestration logic * test to test orchestration logic
...@@ -37,17 +38,16 @@ public class SagaOrchestratorInternallyTest { ...@@ -37,17 +38,16 @@ public class SagaOrchestratorInternallyTest {
@Test @Test
public void executeTest() { public void executeTest() {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery()); var sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result result = sagaOrchestrator.execute(1); var result = sagaOrchestrator.execute(1);
Assert.assertEquals(result, Saga.Result.ROLLBACK); Assert.assertEquals(result, Result.ROLLBACK);
Assert.assertArrayEquals( Assert.assertArrayEquals(
records.toArray(new String[]{}), records.toArray(new String[]{}),
new String[]{"+1", "+2", "+3", "+4", "-4", "-3", "-2", "-1"}); new String[]{"+1", "+2", "+3", "+4", "-4", "-3", "-2", "-1"});
} }
private static Saga newSaga() { private static Saga newSaga() {
return Saga return Saga.create()
.create()
.chapter("1") .chapter("1")
.chapter("2") .chapter("2")
.chapter("3") .chapter("3")
...@@ -55,12 +55,11 @@ public class SagaOrchestratorInternallyTest { ...@@ -55,12 +55,11 @@ public class SagaOrchestratorInternallyTest {
} }
private ServiceDiscoveryService serviceDiscovery() { private ServiceDiscoveryService serviceDiscovery() {
return return new ServiceDiscoveryService()
new ServiceDiscoveryService() .discover(new Service1())
.discover(new Service1()) .discover(new Service2())
.discover(new Service2()) .discover(new Service3())
.discover(new Service3()) .discover(new Service4());
.discover(new Service4());
} }
class Service1 extends Service<Integer> { class Service1 extends Service<Integer> {
......
...@@ -38,7 +38,7 @@ public class App { ...@@ -38,7 +38,7 @@ public class App {
* main method. * main method.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
FruitShop shop = new FruitShop(); var shop = new FruitShop();
new Customer("Peter", shop).start(); new Customer("Peter", shop).start();
new Customer("Paul", shop).start(); new Customer("Paul", shop).start();
new Customer("Mary", shop).start(); new Customer("Mary", shop).start();
......
...@@ -64,13 +64,14 @@ public class Customer extends Thread { ...@@ -64,13 +64,14 @@ public class Customer extends Thread {
public void run() { public void run() {
while (fruitShop.countFruit() > 0) { while (fruitShop.countFruit() > 0) {
FruitBowl bowl = fruitShop.takeBowl(); var bowl = fruitShop.takeBowl();
Fruit fruit; if (bowl != null) {
var fruit = bowl.take();
if (bowl != null && (fruit = bowl.take()) != null) { if (fruit != null) {
LOGGER.info("{} took an {}", name, fruit); LOGGER.info("{} took an {}", name, fruit);
fruitBowl.put(fruit); fruitBowl.put(fruit);
fruitShop.returnBowl(bowl); fruitShop.returnBowl(bowl);
}
} }
} }
......
...@@ -68,11 +68,11 @@ public class FruitBowl { ...@@ -68,11 +68,11 @@ public class FruitBowl {
* toString method. * toString method.
*/ */
public String toString() { public String toString() {
int apples = 0; var apples = 0;
int oranges = 0; var oranges = 0;
int lemons = 0; var lemons = 0;
for (Fruit f : fruit) { for (var f : fruit) {
switch (f.getType()) { switch (f.getType()) {
case APPLE: case APPLE:
apples++; apples++;
......
...@@ -55,7 +55,7 @@ public class FruitShop { ...@@ -55,7 +55,7 @@ public class FruitShop {
* FruitShop constructor. * FruitShop constructor.
*/ */
public FruitShop() { public FruitShop() {
for (int i = 0; i < 100; i++) { for (var i = 0; i < 100; i++) {
bowls[0].put(new Fruit(Fruit.FruitType.APPLE)); bowls[0].put(new Fruit(Fruit.FruitType.APPLE));
bowls[1].put(new Fruit(Fruit.FruitType.ORANGE)); bowls[1].put(new Fruit(Fruit.FruitType.ORANGE));
bowls[2].put(new Fruit(Fruit.FruitType.LEMON)); bowls[2].put(new Fruit(Fruit.FruitType.LEMON));
......
...@@ -25,15 +25,12 @@ package com.iluwatar.semaphore; ...@@ -25,15 +25,12 @@ package com.iluwatar.semaphore;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.IOException;
/** /**
* Application Test Entrypoint * Application Test Entrypoint
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
package com.iluwatar.semaphore; package com.iluwatar.semaphore;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
/** /**
* Test taking from and putting Fruit into a FruitBowl * Test taking from and putting Fruit into a FruitBowl
*/ */
...@@ -36,16 +36,16 @@ public class FruitBowlTest { ...@@ -36,16 +36,16 @@ public class FruitBowlTest {
@Test @Test
public void fruitBowlTest() { public void fruitBowlTest() {
FruitBowl fbowl = new FruitBowl(); var fbowl = new FruitBowl();
assertEquals(0, fbowl.countFruit()); assertEquals(0, fbowl.countFruit());
for (int i = 1; i <= 10; i++) { for (var i = 1; i <= 10; i++) {
fbowl.put(new Fruit(Fruit.FruitType.LEMON)); fbowl.put(new Fruit(Fruit.FruitType.LEMON));
assertEquals(i, fbowl.countFruit()); assertEquals(i, fbowl.countFruit());
} }
for (int i = 9; i >= 0; i--) { for (var i = 9; i >= 0; i--) {
assertNotNull(fbowl.take()); assertNotNull(fbowl.take());
assertEquals(i, fbowl.countFruit()); assertEquals(i, fbowl.countFruit());
} }
......
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
package com.iluwatar.semaphore; package com.iluwatar.semaphore;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
/** /**
* Test case for acquiring and releasing a Semaphore * Test case for acquiring and releasing a Semaphore
*/ */
...@@ -35,11 +35,11 @@ public class SemaphoreTest { ...@@ -35,11 +35,11 @@ public class SemaphoreTest {
@Test @Test
public void acquireReleaseTest() { public void acquireReleaseTest() {
Semaphore sphore = new Semaphore(3); var sphore = new Semaphore(3);
assertEquals(3, sphore.getAvailableLicenses()); assertEquals(3, sphore.getAvailableLicenses());
for (int i = 2; i >= 0; i--) { for (var i = 2; i >= 0; i--) {
try { try {
sphore.acquire(); sphore.acquire();
assertEquals(i, sphore.getAvailableLicenses()); assertEquals(i, sphore.getAvailableLicenses());
...@@ -47,8 +47,8 @@ public class SemaphoreTest { ...@@ -47,8 +47,8 @@ public class SemaphoreTest {
fail(e.toString()); fail(e.toString());
} }
} }
for (int i = 1; i <= 3; i++) { for (var i = 1; i <= 3; i++) {
sphore.release(); sphore.release();
assertEquals(i, sphore.getAvailableLicenses()); assertEquals(i, sphore.getAvailableLicenses());
} }
......
...@@ -54,10 +54,10 @@ public class App { ...@@ -54,10 +54,10 @@ public class App {
* Can add a List with enum Actions for variable scenarios. * Can add a List with enum Actions for variable scenarios.
*/ */
public static void scenario(Servant servant, int compliment) { public static void scenario(Servant servant, int compliment) {
King k = new King(); var k = new King();
Queen q = new Queen(); var q = new Queen();
List<Royalty> guests = List.of(k, q); var guests = List.of(k, q);
// feed // feed
servant.feed(k); servant.feed(k);
...@@ -69,9 +69,7 @@ public class App { ...@@ -69,9 +69,7 @@ public class App {
servant.giveCompliments(guests.get(compliment)); servant.giveCompliments(guests.get(compliment));
// outcome of the night // outcome of the night
for (Royalty r : guests) { guests.forEach(Royalty::changeMood);
r.changeMood();
}
// check your luck // check your luck
if (servant.checkIfYouWillBeHanged(guests)) { if (servant.checkIfYouWillBeHanged(guests)) {
......
...@@ -55,13 +55,6 @@ public class Servant { ...@@ -55,13 +55,6 @@ public class Servant {
* Check if we will be hanged. * Check if we will be hanged.
*/ */
public boolean checkIfYouWillBeHanged(List<Royalty> tableGuests) { public boolean checkIfYouWillBeHanged(List<Royalty> tableGuests) {
boolean anotherDay = true; return tableGuests.stream().allMatch(Royalty::getMood);
for (Royalty r : tableGuests) {
if (!r.getMood()) {
anotherDay = false;
}
}
return anotherDay;
} }
} }
...@@ -26,15 +26,12 @@ package com.iluwatar.servant; ...@@ -26,15 +26,12 @@ package com.iluwatar.servant;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
*
* Application test * Application test
*
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
package com.iluwatar.servant; package com.iluwatar.servant;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 9:40 PM * Date: 12/28/15 - 9:40 PM
* *
...@@ -37,14 +37,14 @@ public class KingTest { ...@@ -37,14 +37,14 @@ public class KingTest {
@Test @Test
public void testHungrySoberUncomplimentedKing() { public void testHungrySoberUncomplimentedKing() {
final King king = new King(); final var king = new King();
king.changeMood(); king.changeMood();
assertFalse(king.getMood()); assertFalse(king.getMood());
} }
@Test @Test
public void testFedSoberUncomplimentedKing() { public void testFedSoberUncomplimentedKing() {
final King king = new King(); final var king = new King();
king.getFed(); king.getFed();
king.changeMood(); king.changeMood();
assertFalse(king.getMood()); assertFalse(king.getMood());
...@@ -52,7 +52,7 @@ public class KingTest { ...@@ -52,7 +52,7 @@ public class KingTest {
@Test @Test
public void testHungryDrunkUncomplimentedKing() { public void testHungryDrunkUncomplimentedKing() {
final King king = new King(); final var king = new King();
king.getDrink(); king.getDrink();
king.changeMood(); king.changeMood();
assertFalse(king.getMood()); assertFalse(king.getMood());
...@@ -60,7 +60,7 @@ public class KingTest { ...@@ -60,7 +60,7 @@ public class KingTest {
@Test @Test
public void testHungrySoberComplimentedKing() { public void testHungrySoberComplimentedKing() {
final King king = new King(); final var king = new King();
king.receiveCompliments(); king.receiveCompliments();
king.changeMood(); king.changeMood();
assertFalse(king.getMood()); assertFalse(king.getMood());
...@@ -68,7 +68,7 @@ public class KingTest { ...@@ -68,7 +68,7 @@ public class KingTest {
@Test @Test
public void testFedDrunkUncomplimentedKing() { public void testFedDrunkUncomplimentedKing() {
final King king = new King(); final var king = new King();
king.getFed(); king.getFed();
king.getDrink(); king.getDrink();
king.changeMood(); king.changeMood();
...@@ -77,7 +77,7 @@ public class KingTest { ...@@ -77,7 +77,7 @@ public class KingTest {
@Test @Test
public void testFedSoberComplimentedKing() { public void testFedSoberComplimentedKing() {
final King king = new King(); final var king = new King();
king.getFed(); king.getFed();
king.receiveCompliments(); king.receiveCompliments();
king.changeMood(); king.changeMood();
...@@ -86,7 +86,7 @@ public class KingTest { ...@@ -86,7 +86,7 @@ public class KingTest {
@Test @Test
public void testFedDrunkComplimentedKing() { public void testFedDrunkComplimentedKing() {
final King king = new King(); final var king = new King();
king.getFed(); king.getFed();
king.getDrink(); king.getDrink();
king.receiveCompliments(); king.receiveCompliments();
......
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
package com.iluwatar.servant; package com.iluwatar.servant;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 9:52 PM * Date: 12/28/15 - 9:52 PM
* *
...@@ -38,34 +38,34 @@ public class QueenTest { ...@@ -38,34 +38,34 @@ public class QueenTest {
@Test @Test
public void testNotFlirtyUncomplemented() { public void testNotFlirtyUncomplemented() {
final Queen queen = new Queen(); final var queen = new Queen();
queen.setFlirtiness(false); queen.setFlirtiness(false);
queen.changeMood(); queen.changeMood();
assertFalse(queen.getMood()); assertFalse(queen.getMood());
} }
@Test @Test
public void testNotFlirtyComplemented() { public void testNotFlirtyComplemented() {
final Queen queen = new Queen(); final var queen = new Queen();
queen.setFlirtiness(false); queen.setFlirtiness(false);
queen.receiveCompliments(); queen.receiveCompliments();
queen.changeMood(); queen.changeMood();
assertFalse(queen.getMood()); assertFalse(queen.getMood());
} }
@Test @Test
public void testFlirtyUncomplemented() { public void testFlirtyUncomplemented() {
final Queen queen = new Queen(); final var queen = new Queen();
queen.changeMood(); queen.changeMood();
assertFalse(queen.getMood()); assertFalse(queen.getMood());
} }
@Test @Test
public void testFlirtyComplemented() { public void testFlirtyComplemented() {
final Queen queen = new Queen(); final var queen = new Queen();
queen.receiveCompliments(); queen.receiveCompliments();
queen.changeMood(); queen.changeMood();
assertTrue(queen.getMood()); assertTrue(queen.getMood());
} }
} }
\ No newline at end of file
...@@ -23,16 +23,15 @@ ...@@ -23,16 +23,15 @@
package com.iluwatar.servant; package com.iluwatar.servant;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.List;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 10:02 PM * Date: 12/28/15 - 10:02 PM
* *
...@@ -42,8 +41,8 @@ public class ServantTest { ...@@ -42,8 +41,8 @@ public class ServantTest {
@Test @Test
public void testFeed() { public void testFeed() {
final Royalty royalty = mock(Royalty.class); final var royalty = mock(Royalty.class);
final Servant servant = new Servant("test"); final var servant = new Servant("test");
servant.feed(royalty); servant.feed(royalty);
verify(royalty).getFed(); verify(royalty).getFed();
verifyNoMoreInteractions(royalty); verifyNoMoreInteractions(royalty);
...@@ -51,8 +50,8 @@ public class ServantTest { ...@@ -51,8 +50,8 @@ public class ServantTest {
@Test @Test
public void testGiveWine() { public void testGiveWine() {
final Royalty royalty = mock(Royalty.class); final var royalty = mock(Royalty.class);
final Servant servant = new Servant("test"); final var servant = new Servant("test");
servant.giveWine(royalty); servant.giveWine(royalty);
verify(royalty).getDrink(); verify(royalty).getDrink();
verifyNoMoreInteractions(royalty); verifyNoMoreInteractions(royalty);
...@@ -60,8 +59,8 @@ public class ServantTest { ...@@ -60,8 +59,8 @@ public class ServantTest {
@Test @Test
public void testGiveCompliments() { public void testGiveCompliments() {
final Royalty royalty = mock(Royalty.class); final var royalty = mock(Royalty.class);
final Servant servant = new Servant("test"); final var servant = new Servant("test");
servant.giveCompliments(royalty); servant.giveCompliments(royalty);
verify(royalty).receiveCompliments(); verify(royalty).receiveCompliments();
verifyNoMoreInteractions(royalty); verifyNoMoreInteractions(royalty);
...@@ -69,15 +68,15 @@ public class ServantTest { ...@@ -69,15 +68,15 @@ public class ServantTest {
@Test @Test
public void testCheckIfYouWillBeHanged() { public void testCheckIfYouWillBeHanged() {
final Royalty goodMoodRoyalty = mock(Royalty.class); final var goodMoodRoyalty = mock(Royalty.class);
when(goodMoodRoyalty.getMood()).thenReturn(true); when(goodMoodRoyalty.getMood()).thenReturn(true);
final Royalty badMoodRoyalty = mock(Royalty.class); final var badMoodRoyalty = mock(Royalty.class);
when(badMoodRoyalty.getMood()).thenReturn(true); when(badMoodRoyalty.getMood()).thenReturn(true);
final List<Royalty> goodCompany = List.of(goodMoodRoyalty, goodMoodRoyalty, goodMoodRoyalty); final var goodCompany = List.of(goodMoodRoyalty, goodMoodRoyalty, goodMoodRoyalty);
final List<Royalty> badCompany = List.of(goodMoodRoyalty, goodMoodRoyalty, badMoodRoyalty); final var badCompany = List.of(goodMoodRoyalty, goodMoodRoyalty, badMoodRoyalty);
assertTrue(new Servant("test").checkIfYouWillBeHanged(goodCompany)); assertTrue(new Servant("test").checkIfYouWillBeHanged(goodCompany));
assertTrue(new Servant("test").checkIfYouWillBeHanged(badCompany)); assertTrue(new Servant("test").checkIfYouWillBeHanged(badCompany));
......
...@@ -24,14 +24,12 @@ ...@@ -24,14 +24,12 @@
package com.iluwatar.serverless.baas.api; package com.iluwatar.serverless.baas.api;
import com.amazonaws.regions.Regions; import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
...@@ -50,7 +48,7 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> { ...@@ -50,7 +48,7 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> {
} }
private void initAmazonDynamoDb() { private void initAmazonDynamoDb() {
AmazonDynamoDB amazonDynamoDb = AmazonDynamoDBClientBuilder var amazonDynamoDb = AmazonDynamoDBClientBuilder
.standard() .standard()
.withRegion(Regions.US_EAST_1) .withRegion(Regions.US_EAST_1)
.build(); .build();
...@@ -71,10 +69,7 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> { ...@@ -71,10 +69,7 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> {
} }
protected Map<String, String> headers() { protected Map<String, String> headers() {
Map<String, String> headers = new HashMap<>(); return Map.of("Content-Type", "application/json");
headers.put("Content-Type", "application/json");
return headers;
} }
/** /**
...@@ -85,14 +80,11 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> { ...@@ -85,14 +80,11 @@ public abstract class AbstractDynamoDbHandler<T extends Serializable> {
* @return - api gateway proxy response * @return - api gateway proxy response
*/ */
protected APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent(Integer statusCode, T body) { protected APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent(Integer statusCode, T body) {
APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent = var apiGatewayProxyResponseEvent = new APIGatewayProxyResponseEvent().withHeaders(headers());
new APIGatewayProxyResponseEvent().withHeaders(headers());
try { try {
apiGatewayProxyResponseEvent apiGatewayProxyResponseEvent
.withStatusCode(statusCode) .withStatusCode(statusCode)
.withBody(getObjectMapper() .withBody(getObjectMapper().writeValueAsString(body));
.writeValueAsString(body));
} catch (JsonProcessingException jsonProcessingException) { } catch (JsonProcessingException jsonProcessingException) {
throw new RuntimeException(jsonProcessingException); throw new RuntimeException(jsonProcessingException);
} }
......
...@@ -28,7 +28,6 @@ import com.amazonaws.services.lambda.runtime.RequestHandler; ...@@ -28,7 +28,6 @@ import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.iluwatar.serverless.baas.model.Person; import com.iluwatar.serverless.baas.model.Person;
import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -42,15 +41,15 @@ public class FindPersonApiHandler extends AbstractDynamoDbHandler<Person> ...@@ -42,15 +41,15 @@ public class FindPersonApiHandler extends AbstractDynamoDbHandler<Person>
private static final Integer SUCCESS_STATUS_CODE = 200; private static final Integer SUCCESS_STATUS_CODE = 200;
@Override @Override
public APIGatewayProxyResponseEvent handleRequest( public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent req, Context ctx) {
APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent, Context context) { req.getPathParameters().forEach(FindPersonApiHandler::logKeyValue);
Map<String, String> pathParameters = apiGatewayProxyRequestEvent.getPathParameters(); var id = req.getPathParameters().get("id");
pathParameters.keySet().stream().map(key -> key + "=" + pathParameters.get(key)) var person = this.getDynamoDbMapper().load(Person.class, id);
.forEach(LOG::info);
Person person = this.getDynamoDbMapper().load(Person.class, apiGatewayProxyRequestEvent
.getPathParameters().get("id"));
return apiGatewayProxyResponseEvent(SUCCESS_STATUS_CODE, person); return apiGatewayProxyResponseEvent(SUCCESS_STATUS_CODE, person);
} }
private static void logKeyValue(String key, String value) {
LOG.info(key + "=" + value);
}
} }
...@@ -43,19 +43,15 @@ public class SavePersonApiHandler extends AbstractDynamoDbHandler<Person> ...@@ -43,19 +43,15 @@ public class SavePersonApiHandler extends AbstractDynamoDbHandler<Person>
private static final Integer BAD_REQUEST_STATUS_CODE = 400; private static final Integer BAD_REQUEST_STATUS_CODE = 400;
@Override @Override
public APIGatewayProxyResponseEvent handleRequest( public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent req, Context ctx) {
APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent, Context context) {
APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent;
Person person;
try { try {
person = getObjectMapper().readValue(apiGatewayProxyRequestEvent.getBody(), Person.class); var objectMapper = getObjectMapper();
var person = objectMapper.readValue(req.getBody(), Person.class);
getDynamoDbMapper().save(person); getDynamoDbMapper().save(person);
apiGatewayProxyResponseEvent = apiGatewayProxyResponseEvent(CREATED_STATUS_CODE, person); return apiGatewayProxyResponseEvent(CREATED_STATUS_CODE, person);
} catch (IOException ioException) { } catch (IOException ioException) {
LOG.error("unable to parse body", ioException); LOG.error("unable to parse body", ioException);
apiGatewayProxyResponseEvent = apiGatewayProxyResponseEvent(BAD_REQUEST_STATUS_CODE, null); return apiGatewayProxyResponseEvent(BAD_REQUEST_STATUS_CODE, null);
} }
return apiGatewayProxyResponseEvent;
} }
} }
...@@ -26,6 +26,7 @@ package com.iluwatar.serverless.baas.model; ...@@ -26,6 +26,7 @@ package com.iluwatar.serverless.baas.model;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
/** /**
* Address class Created by dheeraj.mummarareddy on 3/4/18. * Address class Created by dheeraj.mummarareddy on 3/4/18.
...@@ -96,30 +97,30 @@ public class Address implements Serializable { ...@@ -96,30 +97,30 @@ public class Address implements Serializable {
return false; return false;
} }
Address address = (Address) o; var address = (Address) o;
if (addressLineOne != null ? !addressLineOne.equals(address.addressLineOne) : if (!Objects.equals(addressLineOne, address.addressLineOne)) {
address.addressLineOne != null) {
return false; return false;
} }
if (addressLineTwo != null ? !addressLineTwo.equals(address.addressLineTwo) : if (!Objects.equals(addressLineTwo, address.addressLineTwo)) {
address.addressLineTwo != null) {
return false; return false;
} }
if (city != null ? !city.equals(address.city) : address.city != null) { if (!Objects.equals(city, address.city)) {
return false; return false;
} }
if (state != null ? !state.equals(address.state) : address.state != null) {
if (!Objects.equals(state, address.state)) {
return false; return false;
} }
return zipCode != null ? zipCode.equals(address.zipCode) : address.zipCode == null;
return Objects.equals(zipCode, address.zipCode);
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = addressLineOne != null ? addressLineOne.hashCode() : 0; var result = addressLineOne != null ? addressLineOne.hashCode() : 0;
result = 31 * result + (addressLineTwo != null ? addressLineTwo.hashCode() : 0); result = 31 * result + (addressLineTwo != null ? addressLineTwo.hashCode() : 0);
result = 31 * result + (city != null ? city.hashCode() : 0); result = 31 * result + (city != null ? city.hashCode() : 0);
result = 31 * result + (state != null ? state.hashCode() : 0); result = 31 * result + (state != null ? state.hashCode() : 0);
......
...@@ -29,6 +29,7 @@ import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; ...@@ -29,6 +29,7 @@ import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
/** /**
* Person class Created by dheeraj.mummarareddy on 3/4/18. * Person class Created by dheeraj.mummarareddy on 3/4/18.
...@@ -92,15 +93,15 @@ public class Person implements Serializable { ...@@ -92,15 +93,15 @@ public class Person implements Serializable {
Person person = (Person) o; Person person = (Person) o;
if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) { if (!Objects.equals(firstName, person.firstName)) {
return false; return false;
} }
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) { if (!Objects.equals(lastName, person.lastName)) {
return false; return false;
} }
return address != null ? address.equals(person.address) : person.address == null; return Objects.equals(address, person.address);
} }
@Override @Override
......
...@@ -30,10 +30,8 @@ import java.util.Map; ...@@ -30,10 +30,8 @@ import java.util.Map;
/** /**
* Api gateway response. * Api gateway response.
*
* @param <T> serializable object
*/ */
public class ApiGatewayResponse<T extends Serializable> implements Serializable { public class ApiGatewayResponse implements Serializable {
private static final long serialVersionUID = 1181159426782844892L; private static final long serialVersionUID = 1181159426782844892L;
...@@ -50,8 +48,12 @@ public class ApiGatewayResponse<T extends Serializable> implements Serializable ...@@ -50,8 +48,12 @@ public class ApiGatewayResponse<T extends Serializable> implements Serializable
* @param headers - response headers * @param headers - response headers
* @param isBase64Encoded - base64Encoded flag * @param isBase64Encoded - base64Encoded flag
*/ */
public ApiGatewayResponse(Integer statusCode, String body, Map<String, String> headers, public ApiGatewayResponse(
Boolean isBase64Encoded) { Integer statusCode,
String body,
Map<String, String> headers,
Boolean isBase64Encoded
) {
this.statusCode = statusCode; this.statusCode = statusCode;
this.body = body; this.body = body;
this.headers = headers; this.headers = headers;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
package com.iluwatar.serverless.faas; package com.iluwatar.serverless.faas;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
/** /**
* Lambda context information. * Lambda context information.
...@@ -110,28 +111,22 @@ public class LambdaInfo implements Serializable { ...@@ -110,28 +111,22 @@ public class LambdaInfo implements Serializable {
LambdaInfo that = (LambdaInfo) o; LambdaInfo that = (LambdaInfo) o;
if (awsRequestId != null ? !awsRequestId if (!Objects.equals(awsRequestId, that.awsRequestId)) {
.equals(that.awsRequestId) : that.awsRequestId != null) {
return false; return false;
} }
if (logGroupName != null ? !logGroupName if (!Objects.equals(logGroupName, that.logGroupName)) {
.equals(that.logGroupName) : that.logGroupName != null) {
return false; return false;
} }
if (logStreamName != null ? !logStreamName if (!Objects.equals(logStreamName, that.logStreamName)) {
.equals(that.logStreamName) : that.logStreamName != null) {
return false; return false;
} }
if (functionName != null ? !functionName if (!Objects.equals(functionName, that.functionName)) {
.equals(that.functionName) : that.functionName != null) {
return false; return false;
} }
if (functionVersion != null ? !functionVersion if (!Objects.equals(functionVersion, that.functionVersion)) {
.equals(that.functionVersion) : that.functionVersion != null) {
return false; return false;
} }
return memoryLimitInMb != null ? memoryLimitInMb return Objects.equals(memoryLimitInMb, that.memoryLimitInMb);
.equals(that.memoryLimitInMb) : that.memoryLimitInMb == null;
} }
@Override @Override
......
...@@ -27,7 +27,6 @@ import com.amazonaws.services.lambda.runtime.Context; ...@@ -27,7 +27,6 @@ import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.iluwatar.serverless.faas.ApiGatewayResponse; import com.iluwatar.serverless.faas.ApiGatewayResponse;
import com.iluwatar.serverless.faas.LambdaInfo; import com.iluwatar.serverless.faas.LambdaInfo;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -46,13 +45,11 @@ public class LambdaInfoApiHandler ...@@ -46,13 +45,11 @@ public class LambdaInfoApiHandler
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) { public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
LOG.info("received: " + input); LOG.info("received: " + input);
return new ApiGatewayResponse return new ApiGatewayResponse.ApiGatewayResponseBuilder<LambdaInfo>()
.ApiGatewayResponseBuilder<LambdaInfo>()
.headers(headers()) .headers(headers())
.statusCode(SUCCESS_STATUS_CODE) .statusCode(SUCCESS_STATUS_CODE)
.body(lambdaInfo(context)) .body(lambdaInfo(context))
.build(); .build();
} }
/** /**
...@@ -69,14 +66,10 @@ public class LambdaInfoApiHandler ...@@ -69,14 +66,10 @@ public class LambdaInfoApiHandler
lambdaInfo.setLogGroupName(context.getLogGroupName()); lambdaInfo.setLogGroupName(context.getLogGroupName());
lambdaInfo.setLogStreamName(context.getLogStreamName()); lambdaInfo.setLogStreamName(context.getLogStreamName());
lambdaInfo.setMemoryLimitInMb(context.getMemoryLimitInMB()); lambdaInfo.setMemoryLimitInMb(context.getMemoryLimitInMB());
return lambdaInfo; return lambdaInfo;
} }
private Map<String, String> headers() { private Map<String, String> headers() {
var headers = new HashMap<String, String>(); return Map.of("Content-Type", "application/json");
headers.put("Content-Type", "application/json");
return headers;
} }
} }
...@@ -23,27 +23,23 @@ ...@@ -23,27 +23,23 @@
package com.iluwatar.serverless.baas.api; package com.iluwatar.serverless.baas.api;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.iluwatar.serverless.baas.api.FindPersonApiHandler;
import com.iluwatar.serverless.baas.api.SavePersonApiHandler;
import com.iluwatar.serverless.baas.model.Person; import com.iluwatar.serverless.baas.model.Person;
import java.util.Map;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import java.util.Collections;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/** /**
* Unit tests for FindPersonApiHandler * Unit tests for FindPersonApiHandler Created by dheeraj.mummar on 3/5/18.
* Created by dheeraj.mummar on 3/5/18.
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class FindPersonApiHandlerTest { public class FindPersonApiHandlerTest {
...@@ -66,8 +62,7 @@ public class FindPersonApiHandlerTest { ...@@ -66,8 +62,7 @@ public class FindPersonApiHandlerTest {
} }
private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent() { private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent() {
return new APIGatewayProxyRequestEvent() var request = new APIGatewayProxyRequestEvent();
.withPathParamters(Collections return request.withPathParamters(Map.of("id", "37e7a1fe-3544-473d-b764-18128f02d72d"));
.singletonMap("id", "37e7a1fe-3544-473d-b764-18128f02d72d"));
} }
} }
...@@ -23,13 +23,15 @@ ...@@ -23,13 +23,15 @@
package com.iluwatar.serverless.baas.api; package com.iluwatar.serverless.baas.api;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.iluwatar.serverless.baas.api.SavePersonApiHandler;
import com.iluwatar.serverless.baas.model.Address; import com.iluwatar.serverless.baas.model.Address;
import com.iluwatar.serverless.baas.model.Person; import com.iluwatar.serverless.baas.model.Person;
import org.junit.Assert; import org.junit.Assert;
...@@ -39,11 +41,8 @@ import org.junit.runner.RunWith; ...@@ -39,11 +41,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Mockito.*;
/** /**
* Unit tests for SavePersonApiHandler * Unit tests for SavePersonApiHandler Created by dheeraj.mummar on 3/4/18.
* Created by dheeraj.mummar on 3/4/18.
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class SavePersonApiHandlerTest { public class SavePersonApiHandlerTest {
...@@ -63,40 +62,40 @@ public class SavePersonApiHandlerTest { ...@@ -63,40 +62,40 @@ public class SavePersonApiHandlerTest {
@Test @Test
public void handleRequestSavePersonSuccessful() throws JsonProcessingException { public void handleRequestSavePersonSuccessful() throws JsonProcessingException {
Person person = newPerson(); var person = newPerson();
APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent = var body = objectMapper.writeValueAsString(person);
this.savePersonApiHandler var request = apiGatewayProxyRequestEvent(body);
.handleRequest(apiGatewayProxyRequestEvent(objectMapper.writeValueAsString(person)), mock(Context.class)); var ctx = mock(Context.class);
var apiGatewayProxyResponseEvent = this.savePersonApiHandler.handleRequest(request, ctx);
verify(dynamoDbMapper, times(1)).save(person); verify(dynamoDbMapper, times(1)).save(person);
Assert.assertNotNull(apiGatewayProxyResponseEvent); Assert.assertNotNull(apiGatewayProxyResponseEvent);
Assert.assertEquals(new Integer(201), apiGatewayProxyResponseEvent.getStatusCode()); Assert.assertEquals(Integer.valueOf(201), apiGatewayProxyResponseEvent.getStatusCode());
} }
@Test @Test
public void handleRequestSavePersonException() { public void handleRequestSavePersonException() {
APIGatewayProxyResponseEvent apiGatewayProxyResponseEvent = var request = apiGatewayProxyRequestEvent("invalid sample request");
this.savePersonApiHandler var ctx = mock(Context.class);
.handleRequest(apiGatewayProxyRequestEvent("invalid sample request"), mock(Context.class)); var apiGatewayProxyResponseEvent = this.savePersonApiHandler.handleRequest(request, ctx);
Assert.assertNotNull(apiGatewayProxyResponseEvent); Assert.assertNotNull(apiGatewayProxyResponseEvent);
Assert.assertEquals(new Integer(400), apiGatewayProxyResponseEvent.getStatusCode()); Assert.assertEquals(Integer.valueOf(400), apiGatewayProxyResponseEvent.getStatusCode());
} }
private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent(String body) { private APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent(String body) {
APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent = new APIGatewayProxyRequestEvent(); var apiGatewayProxyRequestEvent = new APIGatewayProxyRequestEvent();
return apiGatewayProxyRequestEvent.withBody(body); return apiGatewayProxyRequestEvent.withBody(body);
} }
private Person newPerson() { private Person newPerson() {
Person person = new Person(); var person = new Person();
person.setFirstName("Thor"); person.setFirstName("Thor");
person.setLastName("Odinson"); person.setLastName("Odinson");
Address address = new Address(); var address = new Address();
address.setAddressLineOne("1 Odin ln"); address.setAddressLineOne("1 Odin ln");
address.setCity("Asgard"); address.setCity("Asgard");
address.setState("country of the Gods"); address.setState("country of the Gods");
address.setZipCode("00001"); address.setZipCode("00001");
person.setAddress(address); person.setAddress(address);
return person; return person;
} }
} }
...@@ -23,16 +23,16 @@ ...@@ -23,16 +23,16 @@
package com.iluwatar.serverless.faas.api; package com.iluwatar.serverless.faas.api;
import com.amazonaws.services.lambda.runtime.Context;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.notNullValue; import static org.hamcrest.core.IsNull.notNullValue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.amazonaws.services.lambda.runtime.Context;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/** /**
* Unit tests for LambdaInfoApiHandler * Unit tests for LambdaInfoApiHandler
*/ */
...@@ -41,8 +41,8 @@ public class LambdaInfoApiHandlerTest { ...@@ -41,8 +41,8 @@ public class LambdaInfoApiHandlerTest {
@Test @Test
public void handleRequestWithMockContext() { public void handleRequestWithMockContext() {
LambdaInfoApiHandler lambdaInfoApiHandler = new LambdaInfoApiHandler(); var lambdaInfoApiHandler = new LambdaInfoApiHandler();
Context context = mock(Context.class); var context = mock(Context.class);
when(context.getAwsRequestId()).thenReturn("mock aws request id"); when(context.getAwsRequestId()).thenReturn("mock aws request id");
assertThat(lambdaInfoApiHandler.handleRequest(null, context), notNullValue()); assertThat(lambdaInfoApiHandler.handleRequest(null, context), notNullValue());
......
...@@ -31,7 +31,6 @@ import com.iluwatar.servicelayer.spellbook.Spellbook; ...@@ -31,7 +31,6 @@ import com.iluwatar.servicelayer.spellbook.Spellbook;
import com.iluwatar.servicelayer.spellbook.SpellbookDaoImpl; import com.iluwatar.servicelayer.spellbook.SpellbookDaoImpl;
import com.iluwatar.servicelayer.wizard.Wizard; import com.iluwatar.servicelayer.wizard.Wizard;
import com.iluwatar.servicelayer.wizard.WizardDaoImpl; import com.iluwatar.servicelayer.wizard.WizardDaoImpl;
import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -178,29 +177,21 @@ public class App { ...@@ -178,29 +177,21 @@ public class App {
* Query the data. * Query the data.
*/ */
public static void queryData() { public static void queryData() {
var service = var wizardDao = new WizardDaoImpl();
new MagicServiceImpl(new WizardDaoImpl(), new SpellbookDaoImpl(), new SpellDaoImpl()); var spellbookDao = new SpellbookDaoImpl();
var spellDao = new SpellDaoImpl();
var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
LOGGER.info("Enumerating all wizards"); LOGGER.info("Enumerating all wizards");
for (Wizard w : service.findAllWizards()) { service.findAllWizards().stream().map(Wizard::getName).forEach(LOGGER::info);
LOGGER.info(w.getName());
}
LOGGER.info("Enumerating all spellbooks"); LOGGER.info("Enumerating all spellbooks");
for (Spellbook s : service.findAllSpellbooks()) { service.findAllSpellbooks().stream().map(Spellbook::getName).forEach(LOGGER::info);
LOGGER.info(s.getName());
}
LOGGER.info("Enumerating all spells"); LOGGER.info("Enumerating all spells");
for (Spell s : service.findAllSpells()) { service.findAllSpells().stream().map(Spell::getName).forEach(LOGGER::info);
LOGGER.info(s.getName());
}
LOGGER.info("Find wizards with spellbook 'Book of Idores'"); LOGGER.info("Find wizards with spellbook 'Book of Idores'");
List<Wizard> wizardsWithSpellbook = service.findWizardsWithSpellbook("Book of Idores"); var wizardsWithSpellbook = service.findWizardsWithSpellbook("Book of Idores");
for (Wizard w : wizardsWithSpellbook) { wizardsWithSpellbook.forEach(w -> LOGGER.info("{} has 'Book of Idores'", w.getName()));
LOGGER.info("{} has 'Book of Idores'", w.getName());
}
LOGGER.info("Find wizards with spell 'Fireball'"); LOGGER.info("Find wizards with spell 'Fireball'");
List<Wizard> wizardsWithSpell = service.findWizardsWithSpell("Fireball"); var wizardsWithSpell = service.findWizardsWithSpell("Fireball");
for (Wizard w : wizardsWithSpell) { wizardsWithSpell.forEach(w -> LOGGER.info("{} has 'Fireball'", w.getName()));
LOGGER.info("{} has 'Fireball'", w.getName());
}
} }
} }
...@@ -52,10 +52,9 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -52,10 +52,9 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
@Override @Override
public E find(Long id) { public E find(Long id) {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
E result = null; E result;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
var criteria = session.createCriteria(persistentClass); var criteria = session.createCriteria(persistentClass);
criteria.add(Restrictions.idEq(id)); criteria.add(Restrictions.idEq(id));
...@@ -66,17 +65,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -66,17 +65,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
return result; return result;
} }
@Override @Override
public void persist(E entity) { public void persist(E entity) {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
session.persist(entity); session.persist(entity);
tx.commit(); tx.commit();
...@@ -85,17 +81,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -85,17 +81,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
} }
@Override @Override
public E merge(E entity) { public E merge(E entity) {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
E result = null; E result = null;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
result = (E) session.merge(entity); result = (E) session.merge(entity);
tx.commit(); tx.commit();
...@@ -104,17 +97,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -104,17 +97,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
return result; return result;
} }
@Override @Override
public void delete(E entity) { public void delete(E entity) {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
session.delete(entity); session.delete(entity);
tx.commit(); tx.commit();
...@@ -123,17 +113,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -123,17 +113,14 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
} }
@Override @Override
public List<E> findAll() { public List<E> findAll() {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
List<E> result = null; List<E> result;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
Criteria criteria = session.createCriteria(persistentClass); Criteria criteria = session.createCriteria(persistentClass);
result = criteria.list(); result = criteria.list();
...@@ -142,8 +129,6 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> { ...@@ -142,8 +129,6 @@ public abstract class DaoBaseImpl<E extends BaseEntity> implements Dao<E> {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
return result; return result;
} }
......
...@@ -54,14 +54,15 @@ public final class HibernateUtil { ...@@ -54,14 +54,15 @@ public final class HibernateUtil {
public static synchronized SessionFactory getSessionFactory() { public static synchronized SessionFactory getSessionFactory() {
if (sessionFactory == null) { if (sessionFactory == null) {
try { try {
sessionFactory = sessionFactory = new Configuration()
new Configuration().addAnnotatedClass(Wizard.class).addAnnotatedClass(Spellbook.class) .addAnnotatedClass(Wizard.class)
.addAnnotatedClass(Spell.class) .addAnnotatedClass(Spellbook.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect") .addAnnotatedClass(Spell.class)
.setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1") .setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.setProperty("hibernate.current_session_context_class", "thread") .setProperty("hibernate.connection.url", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
.setProperty("hibernate.show_sql", "false") .setProperty("hibernate.current_session_context_class", "thread")
.setProperty("hibernate.hbm2ddl.auto", "create-drop").buildSessionFactory(); .setProperty("hibernate.show_sql", "false")
.setProperty("hibernate.hbm2ddl.auto", "create-drop").buildSessionFactory();
} catch (Throwable ex) { } catch (Throwable ex) {
LOGGER.error("Initial SessionFactory creation failed.", ex); LOGGER.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex); throw new ExceptionInInitializerError(ex);
......
...@@ -35,7 +35,7 @@ public class SpellDaoImpl extends DaoBaseImpl<Spell> implements SpellDao { ...@@ -35,7 +35,7 @@ public class SpellDaoImpl extends DaoBaseImpl<Spell> implements SpellDao {
@Override @Override
public Spell findByName(String name) { public Spell findByName(String name) {
Transaction tx = null; Transaction tx = null;
Spell result = null; Spell result;
try (var session = getSessionFactory().openSession()) { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
var criteria = session.createCriteria(persistentClass); var criteria = session.createCriteria(persistentClass);
......
...@@ -34,24 +34,19 @@ public class SpellbookDaoImpl extends DaoBaseImpl<Spellbook> implements Spellboo ...@@ -34,24 +34,19 @@ public class SpellbookDaoImpl extends DaoBaseImpl<Spellbook> implements Spellboo
@Override @Override
public Spellbook findByName(String name) { public Spellbook findByName(String name) {
var session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
Spellbook result = null; Spellbook result;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
var criteria = session.createCriteria(persistentClass); var criteria = session.createCriteria(persistentClass);
criteria.add(Restrictions.eq("name", name)); criteria.add(Restrictions.eq("name", name));
result = (Spellbook) criteria.uniqueResult(); result = (Spellbook) criteria.uniqueResult();
result.getSpells().size();
result.getWizards().size();
tx.commit(); tx.commit();
} catch (Exception e) { } catch (Exception e) {
if (tx != null) { if (tx != null) {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
return result; return result;
} }
......
...@@ -24,9 +24,6 @@ ...@@ -24,9 +24,6 @@
package com.iluwatar.servicelayer.wizard; package com.iluwatar.servicelayer.wizard;
import com.iluwatar.servicelayer.common.DaoBaseImpl; import com.iluwatar.servicelayer.common.DaoBaseImpl;
import com.iluwatar.servicelayer.spellbook.Spellbook;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions; import org.hibernate.criterion.Restrictions;
...@@ -37,25 +34,19 @@ public class WizardDaoImpl extends DaoBaseImpl<Wizard> implements WizardDao { ...@@ -37,25 +34,19 @@ public class WizardDaoImpl extends DaoBaseImpl<Wizard> implements WizardDao {
@Override @Override
public Wizard findByName(String name) { public Wizard findByName(String name) {
Session session = getSessionFactory().openSession();
Transaction tx = null; Transaction tx = null;
Wizard result = null; Wizard result;
try { try (var session = getSessionFactory().openSession()) {
tx = session.beginTransaction(); tx = session.beginTransaction();
Criteria criteria = session.createCriteria(persistentClass); var criteria = session.createCriteria(persistentClass);
criteria.add(Restrictions.eq("name", name)); criteria.add(Restrictions.eq("name", name));
result = (Wizard) criteria.uniqueResult(); result = (Wizard) criteria.uniqueResult();
for (Spellbook s : result.getSpellbooks()) {
s.getSpells().size();
}
tx.commit(); tx.commit();
} catch (Exception e) { } catch (Exception e) {
if (tx != null) { if (tx != null) {
tx.rollback(); tx.rollback();
} }
throw e; throw e;
} finally {
session.close();
} }
return result; return result;
} }
......
...@@ -28,16 +28,13 @@ import org.junit.jupiter.api.AfterEach; ...@@ -28,16 +28,13 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
*
* Application test * Application test
*
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
@AfterEach @AfterEach
......
...@@ -23,22 +23,20 @@ ...@@ -23,22 +23,20 @@
package com.iluwatar.servicelayer.common; package com.iluwatar.servicelayer.common;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import com.iluwatar.servicelayer.hibernate.HibernateUtil; import com.iluwatar.servicelayer.hibernate.HibernateUtil;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
/** /**
* Date: 12/28/15 - 10:53 PM * Date: 12/28/15 - 10:53 PM Test for Base Data Access Objects
* Test for Base Data Access Objects *
* @param <E> Type of Base Entity * @param <E> Type of Base Entity
* @param <D> Type of Dao Base Implementation * @param <D> Type of Dao Base Implementation
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
...@@ -79,8 +77,8 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E> ...@@ -79,8 +77,8 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E>
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
for (int i = 0; i < INITIAL_COUNT; i++) { for (int i = 0; i < INITIAL_COUNT; i++) {
final String className = dao.persistentClass.getSimpleName(); final var className = dao.persistentClass.getSimpleName();
final String entityName = String.format("%s%d", className, ID_GENERATOR.incrementAndGet()); final var entityName = String.format("%s%d", className, ID_GENERATOR.incrementAndGet());
this.dao.persist(this.factory.apply(entityName)); this.dao.persist(this.factory.apply(entityName));
} }
} }
...@@ -96,9 +94,9 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E> ...@@ -96,9 +94,9 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E>
@Test @Test
public void testFind() { public void testFind() {
final List<E> all = this.dao.findAll(); final var all = this.dao.findAll();
for (final E entity : all) { for (final var entity : all) {
final E byId = this.dao.find(entity.getId()); final var byId = this.dao.find(entity.getId());
assertNotNull(byId); assertNotNull(byId);
assertEquals(byId.getId(), byId.getId()); assertEquals(byId.getId(), byId.getId());
} }
...@@ -106,39 +104,39 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E> ...@@ -106,39 +104,39 @@ public abstract class BaseDaoTest<E extends BaseEntity, D extends DaoBaseImpl<E>
@Test @Test
public void testDelete() { public void testDelete() {
final List<E> originalEntities = this.dao.findAll(); final var originalEntities = this.dao.findAll();
this.dao.delete(originalEntities.get(1)); this.dao.delete(originalEntities.get(1));
this.dao.delete(originalEntities.get(2)); this.dao.delete(originalEntities.get(2));
final List<E> entitiesLeft = this.dao.findAll(); final var entitiesLeft = this.dao.findAll();
assertNotNull(entitiesLeft); assertNotNull(entitiesLeft);
assertEquals(INITIAL_COUNT - 2, entitiesLeft.size()); assertEquals(INITIAL_COUNT - 2, entitiesLeft.size());
} }
@Test @Test
public void testFindAll() { public void testFindAll() {
final List<E> all = this.dao.findAll(); final var all = this.dao.findAll();
assertNotNull(all); assertNotNull(all);
assertEquals(INITIAL_COUNT, all.size()); assertEquals(INITIAL_COUNT, all.size());
} }
@Test @Test
public void testSetId() { public void testSetId() {
final E entity = this.factory.apply("name"); final var entity = this.factory.apply("name");
assertNull(entity.getId()); assertNull(entity.getId());
final Long expectedId = 1L; final var expectedId = 1L;
entity.setId(expectedId); entity.setId(expectedId);
assertEquals(expectedId, entity.getId()); assertEquals(expectedId, entity.getId());
} }
@Test @Test
public void testSetName() { public void testSetName() {
final E entity = this.factory.apply("name"); final var entity = this.factory.apply("name");
assertEquals("name", entity.getName()); assertEquals("name", entity.getName());
assertEquals("name", entity.toString()); assertEquals("name", entity.toString());
final String expectedName = "new name"; final var expectedName = "new name";
entity.setName(expectedName); entity.setName(expectedName);
assertEquals(expectedName, entity.getName()); assertEquals(expectedName, entity.getName());
assertEquals(expectedName, entity.toString()); assertEquals(expectedName, entity.toString());
......
...@@ -23,18 +23,6 @@ ...@@ -23,18 +23,6 @@
package com.iluwatar.servicelayer.magic; package com.iluwatar.servicelayer.magic;
import com.iluwatar.servicelayer.spell.Spell;
import com.iluwatar.servicelayer.spell.SpellDao;
import com.iluwatar.servicelayer.spellbook.Spellbook;
import com.iluwatar.servicelayer.spellbook.SpellbookDao;
import com.iluwatar.servicelayer.wizard.Wizard;
import com.iluwatar.servicelayer.wizard.WizardDao;
import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
...@@ -44,6 +32,15 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; ...@@ -44,6 +32,15 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.iluwatar.servicelayer.spell.Spell;
import com.iluwatar.servicelayer.spell.SpellDao;
import com.iluwatar.servicelayer.spellbook.Spellbook;
import com.iluwatar.servicelayer.spellbook.SpellbookDao;
import com.iluwatar.servicelayer.wizard.Wizard;
import com.iluwatar.servicelayer.wizard.WizardDao;
import java.util.Set;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/29/15 - 12:06 AM * Date: 12/29/15 - 12:06 AM
* *
...@@ -53,11 +50,11 @@ public class MagicServiceImplTest { ...@@ -53,11 +50,11 @@ public class MagicServiceImplTest {
@Test @Test
public void testFindAllWizards() { public void testFindAllWizards() {
final WizardDao wizardDao = mock(WizardDao.class); final var wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class); final var spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class); final var spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); final var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao); verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllWizards(); service.findAllWizards();
...@@ -66,12 +63,12 @@ public class MagicServiceImplTest { ...@@ -66,12 +63,12 @@ public class MagicServiceImplTest {
} }
@Test @Test
public void testFindAllSpellbooks() throws Exception { public void testFindAllSpellbooks() {
final WizardDao wizardDao = mock(WizardDao.class); final var wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class); final var spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class); final var spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); final var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao); verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllSpellbooks(); service.findAllSpellbooks();
...@@ -80,12 +77,12 @@ public class MagicServiceImplTest { ...@@ -80,12 +77,12 @@ public class MagicServiceImplTest {
} }
@Test @Test
public void testFindAllSpells() throws Exception { public void testFindAllSpells() {
final WizardDao wizardDao = mock(WizardDao.class); final var wizardDao = mock(WizardDao.class);
final SpellbookDao spellbookDao = mock(SpellbookDao.class); final var spellbookDao = mock(SpellbookDao.class);
final SpellDao spellDao = mock(SpellDao.class); final var spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); final var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao); verifyZeroInteractions(wizardDao, spellbookDao, spellDao);
service.findAllSpells(); service.findAllSpells();
...@@ -94,26 +91,27 @@ public class MagicServiceImplTest { ...@@ -94,26 +91,27 @@ public class MagicServiceImplTest {
} }
@Test @Test
public void testFindWizardsWithSpellbook() throws Exception { public void testFindWizardsWithSpellbook() {
final String bookname = "bookname"; final var bookname = "bookname";
final Spellbook spellbook = mock(Spellbook.class); final var spellbook = mock(Spellbook.class);
final Set<Wizard> wizards = Set.of( final var wizards = Set.of(
mock(Wizard.class), mock(Wizard.class),
mock(Wizard.class), mock(Wizard.class),
mock(Wizard.class)); mock(Wizard.class)
);
when(spellbook.getWizards()).thenReturn(wizards); when(spellbook.getWizards()).thenReturn(wizards);
final SpellbookDao spellbookDao = mock(SpellbookDao.class); final var spellbookDao = mock(SpellbookDao.class);
when(spellbookDao.findByName(eq(bookname))).thenReturn(spellbook); when(spellbookDao.findByName(eq(bookname))).thenReturn(spellbook);
final WizardDao wizardDao = mock(WizardDao.class); final var wizardDao = mock(WizardDao.class);
final SpellDao spellDao = mock(SpellDao.class); final var spellDao = mock(SpellDao.class);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); final var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook); verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook);
final List<Wizard> result = service.findWizardsWithSpellbook(bookname); final var result = service.findWizardsWithSpellbook(bookname);
verify(spellbookDao).findByName(eq(bookname)); verify(spellbookDao).findByName(eq(bookname));
verify(spellbook).getWizards(); verify(spellbook).getWizards();
...@@ -125,27 +123,28 @@ public class MagicServiceImplTest { ...@@ -125,27 +123,28 @@ public class MagicServiceImplTest {
@Test @Test
public void testFindWizardsWithSpell() throws Exception { public void testFindWizardsWithSpell() throws Exception {
final Set<Wizard> wizards = Set.of( final var wizards = Set.of(
mock(Wizard.class), mock(Wizard.class),
mock(Wizard.class), mock(Wizard.class),
mock(Wizard.class)); mock(Wizard.class)
final Spellbook spellbook = mock(Spellbook.class); );
final var spellbook = mock(Spellbook.class);
when(spellbook.getWizards()).thenReturn(wizards); when(spellbook.getWizards()).thenReturn(wizards);
final SpellbookDao spellbookDao = mock(SpellbookDao.class); final var spellbookDao = mock(SpellbookDao.class);
final WizardDao wizardDao = mock(WizardDao.class); final var wizardDao = mock(WizardDao.class);
final Spell spell = mock(Spell.class); final var spell = mock(Spell.class);
when(spell.getSpellbook()).thenReturn(spellbook); when(spell.getSpellbook()).thenReturn(spellbook);
final String spellName = "spellname"; final var spellName = "spellname";
final SpellDao spellDao = mock(SpellDao.class); final var spellDao = mock(SpellDao.class);
when(spellDao.findByName(eq(spellName))).thenReturn(spell); when(spellDao.findByName(eq(spellName))).thenReturn(spell);
final MagicServiceImpl service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao); final var service = new MagicServiceImpl(wizardDao, spellbookDao, spellDao);
verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook); verifyZeroInteractions(wizardDao, spellbookDao, spellDao, spellbook);
final List<Wizard> result = service.findWizardsWithSpell(spellName); final var result = service.findWizardsWithSpell(spellName);
verify(spellDao).findByName(eq(spellName)); verify(spellDao).findByName(eq(spellName));
verify(spellbook).getWizards(); verify(spellbook).getWizards();
......
...@@ -23,14 +23,12 @@ ...@@ -23,14 +23,12 @@
package com.iluwatar.servicelayer.spell; package com.iluwatar.servicelayer.spell;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 11:02 PM * Date: 12/28/15 - 11:02 PM
* *
...@@ -44,10 +42,10 @@ public class SpellDaoImplTest extends BaseDaoTest<Spell, SpellDaoImpl> { ...@@ -44,10 +42,10 @@ public class SpellDaoImplTest extends BaseDaoTest<Spell, SpellDaoImpl> {
@Test @Test
public void testFindByName() { public void testFindByName() {
final SpellDaoImpl dao = getDao(); final var dao = getDao();
final List<Spell> allSpells = dao.findAll(); final var allSpells = dao.findAll();
for (final Spell spell : allSpells) { for (final var spell : allSpells) {
final Spell spellByName = dao.findByName(spell.getName()); final var spellByName = dao.findByName(spell.getName());
assertNotNull(spellByName); assertNotNull(spellByName);
assertEquals(spell.getId(), spellByName.getId()); assertEquals(spell.getId(), spellByName.getId());
assertEquals(spell.getName(), spellByName.getName()); assertEquals(spell.getName(), spellByName.getName());
......
...@@ -23,14 +23,12 @@ ...@@ -23,14 +23,12 @@
package com.iluwatar.servicelayer.spellbook; package com.iluwatar.servicelayer.spellbook;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 11:44 PM * Date: 12/28/15 - 11:44 PM
* *
...@@ -44,10 +42,10 @@ public class SpellbookDaoImplTest extends BaseDaoTest<Spellbook, SpellbookDaoImp ...@@ -44,10 +42,10 @@ public class SpellbookDaoImplTest extends BaseDaoTest<Spellbook, SpellbookDaoImp
@Test @Test
public void testFindByName() { public void testFindByName() {
final SpellbookDaoImpl dao = getDao(); final var dao = getDao();
final List<Spellbook> allBooks = dao.findAll(); final var allBooks = dao.findAll();
for (final Spellbook book : allBooks) { for (final var book : allBooks) {
final Spellbook spellByName = dao.findByName(book.getName()); final var spellByName = dao.findByName(book.getName());
assertNotNull(spellByName); assertNotNull(spellByName);
assertEquals(book.getId(), spellByName.getId()); assertEquals(book.getId(), spellByName.getId());
assertEquals(book.getName(), spellByName.getName()); assertEquals(book.getName(), spellByName.getName());
......
...@@ -23,14 +23,12 @@ ...@@ -23,14 +23,12 @@
package com.iluwatar.servicelayer.wizard; package com.iluwatar.servicelayer.wizard;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.iluwatar.servicelayer.common.BaseDaoTest;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/28/15 - 11:46 PM * Date: 12/28/15 - 11:46 PM
* *
...@@ -44,10 +42,10 @@ public class WizardDaoImplTest extends BaseDaoTest<Wizard, WizardDaoImpl> { ...@@ -44,10 +42,10 @@ public class WizardDaoImplTest extends BaseDaoTest<Wizard, WizardDaoImpl> {
@Test @Test
public void testFindByName() { public void testFindByName() {
final WizardDaoImpl dao = getDao(); final var dao = getDao();
final List<Wizard> allWizards = dao.findAll(); final var allWizards = dao.findAll();
for (final Wizard spell : allWizards) { for (final var spell : allWizards) {
final Wizard byName = dao.findByName(spell.getName()); final var byName = dao.findByName(spell.getName());
assertNotNull(byName); assertNotNull(byName);
assertEquals(spell.getId(), byName.getId()); assertEquals(spell.getId(), byName.getId());
assertEquals(spell.getName(), byName.getName()); assertEquals(spell.getName(), byName.getName());
......
...@@ -53,15 +53,14 @@ public class ServiceCache { ...@@ -53,15 +53,14 @@ public class ServiceCache {
* @return {@link Service} * @return {@link Service}
*/ */
public Service getService(String serviceName) { public Service getService(String serviceName) {
Service cachedService = null; if (serviceCache.containsKey(serviceName)) {
for (String serviceJndiName : serviceCache.keySet()) { var cachedService = serviceCache.get(serviceName);
if (serviceJndiName.equals(serviceName)) { var name = cachedService.getName();
cachedService = serviceCache.get(serviceJndiName); var id = cachedService.getId();
LOGGER.info("(cache call) Fetched service {}({}) from cache... !", LOGGER.info("(cache call) Fetched service {}({}) from cache... !", name, id);
cachedService.getName(), cachedService.getId()); return cachedService;
}
} }
return cachedService; return null;
} }
/** /**
......
...@@ -26,15 +26,12 @@ package com.iluwatar.servicelocator; ...@@ -26,15 +26,12 @@ package com.iluwatar.servicelocator;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
*
* Application test * Application test
*
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -23,14 +23,15 @@ ...@@ -23,14 +23,15 @@
package com.iluwatar.servicelocator; package com.iluwatar.servicelocator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/29/15 - 19:07 PM * Date: 12/29/15 - 19:07 PM
* *
...@@ -52,12 +53,10 @@ public class ServiceLocatorTest { ...@@ -52,12 +53,10 @@ public class ServiceLocatorTest {
*/ */
@Test @Test
public void testServiceCache() { public void testServiceCache() {
final String[] serviceNames = new String[]{ final var serviceNames = List.of("jndi/serviceA", "jndi/serviceB");
"jndi/serviceA", "jndi/serviceB"
};
for (final String serviceName : serviceNames) { for (final var serviceName : serviceNames) {
final Service service = ServiceLocator.getService(serviceName); final var service = ServiceLocator.getService(serviceName);
assertNotNull(service); assertNotNull(service);
assertEquals(serviceName, service.getName()); assertEquals(serviceName, service.getName());
assertTrue(service.getId() > 0); // The id is generated randomly, but the minimum value is '1' assertTrue(service.getId() > 0); // The id is generated randomly, but the minimum value is '1'
......
...@@ -24,14 +24,14 @@ ...@@ -24,14 +24,14 @@
package com.iluwatar.sharding; package com.iluwatar.sharding;
/** /**
* Sharding pattern means dividing a data store into a set of horizontal partitions * Sharding pattern means dividing a data store into a set of horizontal partitions or shards. This
* or shards. This pattern can improve scalability when storing and accessing large * pattern can improve scalability when storing and accessing large volumes of data.
* volumes of data.
*/ */
public class App { public class App {
/** /**
* Program main entry point. * Program main entry point.
*
* @param args program runtime arguments * @param args program runtime arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
...@@ -45,7 +45,7 @@ public class App { ...@@ -45,7 +45,7 @@ public class App {
var shard2 = new Shard(2); var shard2 = new Shard(2);
var shard3 = new Shard(3); var shard3 = new Shard(3);
ShardManager manager = new LookupShardManager(); var manager = new LookupShardManager();
manager.addNewShard(shard1); manager.addNewShard(shard1);
manager.addNewShard(shard2); manager.addNewShard(shard2);
manager.addNewShard(shard3); manager.addNewShard(shard3);
...@@ -58,27 +58,27 @@ public class App { ...@@ -58,27 +58,27 @@ public class App {
shard2.clearData(); shard2.clearData();
shard3.clearData(); shard3.clearData();
manager = new RangeShardManager(); var rangeShardManager = new RangeShardManager();
manager.addNewShard(shard1); rangeShardManager.addNewShard(shard1);
manager.addNewShard(shard2); rangeShardManager.addNewShard(shard2);
manager.addNewShard(shard3); rangeShardManager.addNewShard(shard3);
manager.storeData(data1); rangeShardManager.storeData(data1);
manager.storeData(data2); rangeShardManager.storeData(data2);
manager.storeData(data3); rangeShardManager.storeData(data3);
manager.storeData(data4); rangeShardManager.storeData(data4);
shard1.clearData(); shard1.clearData();
shard2.clearData(); shard2.clearData();
shard3.clearData(); shard3.clearData();
manager = new HashShardManager(); var hashShardManager = new HashShardManager();
manager.addNewShard(shard1); hashShardManager.addNewShard(shard1);
manager.addNewShard(shard2); hashShardManager.addNewShard(shard2);
manager.addNewShard(shard3); hashShardManager.addNewShard(shard3);
manager.storeData(data1); hashShardManager.storeData(data1);
manager.storeData(data2); hashShardManager.storeData(data2);
manager.storeData(data3); hashShardManager.storeData(data3);
manager.storeData(data4); hashShardManager.storeData(data4);
shard1.clearData(); shard1.clearData();
shard2.clearData(); shard2.clearData();
......
...@@ -58,8 +58,7 @@ public class LookupShardManager extends ShardManager { ...@@ -58,8 +58,7 @@ public class LookupShardManager extends ShardManager {
return lookupMap.get(key); return lookupMap.get(key);
} else { } else {
var shardCount = shardMap.size(); var shardCount = shardMap.size();
var allocatedShardId = new Random().nextInt(shardCount - 1) + 1; return new Random().nextInt(shardCount - 1) + 1;
return allocatedShardId;
} }
} }
......
...@@ -27,8 +27,8 @@ import org.slf4j.Logger; ...@@ -27,8 +27,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* ShardManager with range strategy. This strategy groups related items together * ShardManager with range strategy. This strategy groups related items together in the same shard,
* in the same shard, and orders them by shard key. * and orders them by shard key.
*/ */
public class RangeShardManager extends ShardManager { public class RangeShardManager extends ShardManager {
...@@ -46,21 +46,16 @@ public class RangeShardManager extends ShardManager { ...@@ -46,21 +46,16 @@ public class RangeShardManager extends ShardManager {
@Override @Override
protected int allocateShard(Data data) { protected int allocateShard(Data data) {
var type = data.getType(); var type = data.getType();
var shardId = -1;
switch (type) { switch (type) {
case type1: case type1:
shardId = 1; return 1;
break;
case type2: case type2:
shardId = 2; return 2;
break;
case type3: case type3:
shardId = 3; return 3;
break;
default: default:
break; return -1;
} }
return shardId;
} }
} }
...@@ -32,8 +32,7 @@ public class AppTest { ...@@ -32,8 +32,7 @@ public class AppTest {
@Test @Test
public void testMain() { public void testMain() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
package com.iluwatar.sharding; package com.iluwatar.sharding;
import java.util.Map; import java.util.Map;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -57,7 +56,7 @@ public class LookupShardManagerTest { ...@@ -57,7 +56,7 @@ public class LookupShardManagerTest {
lookupShardManager.storeData(data); lookupShardManager.storeData(data);
var field = LookupShardManager.class.getDeclaredField("lookupMap"); var field = LookupShardManager.class.getDeclaredField("lookupMap");
field.setAccessible(true); field.setAccessible(true);
Map<Integer, Integer> lookupMap = (Map<Integer, Integer>) field.get(lookupShardManager); var lookupMap = (Map<Integer, Integer>) field.get(lookupShardManager);
var shardId = lookupMap.get(1); var shardId = lookupMap.get(1);
var shard = lookupShardManager.getShardById(shardId); var shard = lookupShardManager.getShardById(shardId);
Assert.assertEquals(data, shard.getDataById(1)); Assert.assertEquals(data, shard.getDataById(1));
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
package com.iluwatar.sharding; package com.iluwatar.sharding;
import java.util.Map; import java.util.Map;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
...@@ -57,7 +56,7 @@ public class ShardManagerTest { ...@@ -57,7 +56,7 @@ public class ShardManagerTest {
shardManager.addNewShard(shard); shardManager.addNewShard(shard);
var field = ShardManager.class.getDeclaredField("shardMap"); var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true); field.setAccessible(true);
Map<Integer, Shard> map = (Map<Integer, Shard>) field.get(shardManager); var map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(1, map.size()); Assert.assertEquals(1, map.size());
Assert.assertEquals(shard, map.get(1)); Assert.assertEquals(shard, map.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {
...@@ -73,7 +72,7 @@ public class ShardManagerTest { ...@@ -73,7 +72,7 @@ public class ShardManagerTest {
boolean flag = shardManager.removeShardById(1); boolean flag = shardManager.removeShardById(1);
var field = ShardManager.class.getDeclaredField("shardMap"); var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true); field.setAccessible(true);
Map<Integer, Shard> map = (Map<Integer, Shard>) field.get(shardManager); var map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(true, flag); Assert.assertEquals(true, flag);
Assert.assertEquals(0, map.size()); Assert.assertEquals(0, map.size());
} catch (IllegalAccessException | NoSuchFieldException e) { } catch (IllegalAccessException | NoSuchFieldException e) {
...@@ -83,9 +82,9 @@ public class ShardManagerTest { ...@@ -83,9 +82,9 @@ public class ShardManagerTest {
@Test @Test
public void testGetShardById() { public void testGetShardById() {
Shard shard = new Shard(1); var shard = new Shard(1);
shardManager.addNewShard(shard); shardManager.addNewShard(shard);
Shard tmpShard = shardManager.getShardById(1); var tmpShard = shardManager.getShardById(1);
Assert.assertEquals(shard, tmpShard); Assert.assertEquals(shard, tmpShard);
} }
......
...@@ -25,7 +25,6 @@ package com.iluwatar.sharding; ...@@ -25,7 +25,6 @@ package com.iluwatar.sharding;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
...@@ -48,7 +47,8 @@ public class ShardTest { ...@@ -48,7 +47,8 @@ public class ShardTest {
} }
@After @After
public void tearDown() {} public void tearDown() {
}
@Test @Test
public void testStoreData() { public void testStoreData() {
...@@ -56,7 +56,7 @@ public class ShardTest { ...@@ -56,7 +56,7 @@ public class ShardTest {
shard.storeData(data); shard.storeData(data);
var field = Shard.class.getDeclaredField("dataStore"); var field = Shard.class.getDeclaredField("dataStore");
field.setAccessible(true); field.setAccessible(true);
Map<Integer, Data> dataMap = (Map<Integer, Data>) field.get(shard); var dataMap = (Map<Integer, Data>) field.get(shard);
Assert.assertEquals(1, dataMap.size()); Assert.assertEquals(1, dataMap.size());
Assert.assertEquals(data, dataMap.get(1)); Assert.assertEquals(data, dataMap.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {
...@@ -68,13 +68,13 @@ public class ShardTest { ...@@ -68,13 +68,13 @@ public class ShardTest {
@Test @Test
public void testClearData() { public void testClearData() {
try { try {
Map<Integer, Data> dataMap = new HashMap<>(); var dataMap = new HashMap<Integer, Data>();
dataMap.put(1, data); dataMap.put(1, data);
var field = Shard.class.getDeclaredField("dataStore"); var field = Shard.class.getDeclaredField("dataStore");
field.setAccessible(true); field.setAccessible(true);
field.set(shard, dataMap); field.set(shard, dataMap);
shard.clearData(); shard.clearData();
dataMap = (Map<Integer, Data>) field.get(shard); dataMap = (HashMap<Integer, Data>) field.get(shard);
Assert.assertEquals(0, dataMap.size()); Assert.assertEquals(0, dataMap.size());
} catch (NoSuchFieldException | IllegalAccessException e) { } catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access."); Assert.fail("Fail to modify field access.");
......
...@@ -41,8 +41,8 @@ public enum EnumIvoryTower { ...@@ -41,8 +41,8 @@ public enum EnumIvoryTower {
Then in order to use Then in order to use
```java ```java
EnumIvoryTower enumIvoryTower1 = EnumIvoryTower.INSTANCE; var enumIvoryTower1 = EnumIvoryTower.INSTANCE;
EnumIvoryTower enumIvoryTower2 = EnumIvoryTower.INSTANCE; var enumIvoryTower2 = EnumIvoryTower.INSTANCE;
assertEquals(enumIvoryTower1, enumIvoryTower2); // true assertEquals(enumIvoryTower1, enumIvoryTower2); // true
``` ```
......
...@@ -45,8 +45,7 @@ import org.slf4j.LoggerFactory; ...@@ -45,8 +45,7 @@ import org.slf4j.LoggerFactory;
* example is found in {@link EnumIvoryTower}. At first glance the code looks short and simple. * example is found in {@link EnumIvoryTower}. At first glance the code looks short and simple.
* However, you should be aware of the downsides including committing to implementation strategy, * However, you should be aware of the downsides including committing to implementation strategy,
* extending the enum class, serializability and restrictions to coding. These are extensively * extending the enum class, serializability and restrictions to coding. These are extensively
* discussed in Stack Overflow: * discussed in Stack Overflow: http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing
* http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing
* -a-singleton-with-javas-enum</p> * -a-singleton-with-javas-enum</p>
* *
* <p>{@link ThreadSafeLazyLoadedIvoryTower} is a Singleton implementation that is initialized on * <p>{@link ThreadSafeLazyLoadedIvoryTower} is a Singleton implementation that is initialized on
...@@ -54,9 +53,9 @@ import org.slf4j.LoggerFactory; ...@@ -54,9 +53,9 @@ import org.slf4j.LoggerFactory;
* synchronized.</p> * synchronized.</p>
* *
* <p>Another Singleton implementation that is initialized on demand is found in * <p>Another Singleton implementation that is initialized on demand is found in
* {@link ThreadSafeDoubleCheckLocking}. It is somewhat faster than * {@link ThreadSafeDoubleCheckLocking}. It is somewhat faster than {@link
* {@link ThreadSafeLazyLoadedIvoryTower} since it doesn't synchronize the whole access method but * ThreadSafeLazyLoadedIvoryTower} since it doesn't synchronize the whole access method but only the
* only the method internals on specific conditions.</p> * method internals on specific conditions.</p>
* *
* <p>Yet another way to implement thread safe lazily initialized Singleton can be found in * <p>Yet another way to implement thread safe lazily initialized Singleton can be found in
* {@link InitializingOnDemandHolderIdiom}. However, this implementation requires at least Java 8 * {@link InitializingOnDemandHolderIdiom}. However, this implementation requires at least Java 8
...@@ -80,10 +79,8 @@ public class App { ...@@ -80,10 +79,8 @@ public class App {
LOGGER.info("ivoryTower2={}", ivoryTower2); LOGGER.info("ivoryTower2={}", ivoryTower2);
// lazily initialized singleton // lazily initialized singleton
var threadSafeIvoryTower1 = var threadSafeIvoryTower1 = ThreadSafeLazyLoadedIvoryTower.getInstance();
ThreadSafeLazyLoadedIvoryTower.getInstance(); var threadSafeIvoryTower2 = ThreadSafeLazyLoadedIvoryTower.getInstance();
var threadSafeIvoryTower2 =
ThreadSafeLazyLoadedIvoryTower.getInstance();
LOGGER.info("threadSafeIvoryTower1={}", threadSafeIvoryTower1); LOGGER.info("threadSafeIvoryTower1={}", threadSafeIvoryTower1);
LOGGER.info("threadSafeIvoryTower2={}", threadSafeIvoryTower2); LOGGER.info("threadSafeIvoryTower2={}", threadSafeIvoryTower2);
...@@ -100,11 +97,9 @@ public class App { ...@@ -100,11 +97,9 @@ public class App {
LOGGER.info(dcl2.toString()); LOGGER.info(dcl2.toString());
// initialize on demand holder idiom // initialize on demand holder idiom
var demandHolderIdiom = var demandHolderIdiom = InitializingOnDemandHolderIdiom.getInstance();
InitializingOnDemandHolderIdiom.getInstance();
LOGGER.info(demandHolderIdiom.toString()); LOGGER.info(demandHolderIdiom.toString());
var demandHolderIdiom2 = var demandHolderIdiom2 = InitializingOnDemandHolderIdiom.getInstance();
InitializingOnDemandHolderIdiom.getInstance();
LOGGER.info(demandHolderIdiom2.toString()); LOGGER.info(demandHolderIdiom2.toString());
} }
} }
...@@ -32,7 +32,6 @@ public class AppTest { ...@@ -32,7 +32,6 @@ public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -29,7 +29,7 @@ package com.iluwatar.singleton; ...@@ -29,7 +29,7 @@ package com.iluwatar.singleton;
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class InitializingOnDemandHolderIdiomTest public class InitializingOnDemandHolderIdiomTest
extends SingletonTest<InitializingOnDemandHolderIdiom> { extends SingletonTest<InitializingOnDemandHolderIdiom> {
/** /**
* Create a new singleton test instance using the given 'getInstance' method. * Create a new singleton test instance using the given 'getInstance' method.
......
...@@ -29,13 +29,11 @@ import static org.junit.jupiter.api.Assertions.assertSame; ...@@ -29,13 +29,11 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTimeout; import static org.junit.jupiter.api.Assertions.assertTimeout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
...@@ -73,9 +71,9 @@ public abstract class SingletonTest<S> { ...@@ -73,9 +71,9 @@ public abstract class SingletonTest<S> {
@Test @Test
public void testMultipleCallsReturnTheSameObjectInSameThread() { public void testMultipleCallsReturnTheSameObjectInSameThread() {
// Create several instances in the same calling thread // Create several instances in the same calling thread
S instance1 = this.singletonInstanceMethod.get(); var instance1 = this.singletonInstanceMethod.get();
S instance2 = this.singletonInstanceMethod.get(); var instance2 = this.singletonInstanceMethod.get();
S instance3 = this.singletonInstanceMethod.get(); var instance3 = this.singletonInstanceMethod.get();
// now check they are equal // now check they are equal
assertSame(instance1, instance2); assertSame(instance1, instance2);
assertSame(instance1, instance3); assertSame(instance1, instance3);
...@@ -89,19 +87,18 @@ public abstract class SingletonTest<S> { ...@@ -89,19 +87,18 @@ public abstract class SingletonTest<S> {
public void testMultipleCallsReturnTheSameObjectInDifferentThreads() throws Exception { public void testMultipleCallsReturnTheSameObjectInDifferentThreads() throws Exception {
assertTimeout(ofMillis(10000), () -> { assertTimeout(ofMillis(10000), () -> {
// Create 10000 tasks and inside each callable instantiate the singleton class // Create 10000 tasks and inside each callable instantiate the singleton class
final List<Callable<S>> tasks = new ArrayList<>(); final var tasks = IntStream.range(0, 10000)
for (int i = 0; i < 10000; i++) { .<Callable<S>>mapToObj(i -> this.singletonInstanceMethod::get)
tasks.add(this.singletonInstanceMethod::get); .collect(Collectors.toCollection(ArrayList::new));
}
// Use up to 8 concurrent threads to handle the tasks // Use up to 8 concurrent threads to handle the tasks
final ExecutorService executorService = Executors.newFixedThreadPool(8); final var executorService = Executors.newFixedThreadPool(8);
final List<Future<S>> results = executorService.invokeAll(tasks); final var results = executorService.invokeAll(tasks);
// wait for all of the threads to complete // wait for all of the threads to complete
final S expectedInstance = this.singletonInstanceMethod.get(); final var expectedInstance = this.singletonInstanceMethod.get();
for (Future<S> res : results) { for (var res : results) {
final S instance = res.get(); final var instance = res.get();
assertNotNull(instance); assertNotNull(instance);
assertSame(expectedInstance, instance); assertSame(expectedInstance, instance);
} }
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
package com.iluwatar.singleton; package com.iluwatar.singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import org.junit.Test; import org.junit.Test;
/** /**
...@@ -47,11 +45,10 @@ public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDo ...@@ -47,11 +45,10 @@ public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDo
*/ */
@Test(expected = InvocationTargetException.class) @Test(expected = InvocationTargetException.class)
public void testCreatingNewInstanceByRefection() throws Exception { public void testCreatingNewInstanceByRefection() throws Exception {
ThreadSafeDoubleCheckLocking instance1 = ThreadSafeDoubleCheckLocking.getInstance(); ThreadSafeDoubleCheckLocking.getInstance();
Constructor constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor(); var constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor();
constructor.setAccessible(true); constructor.setAccessible(true);
ThreadSafeDoubleCheckLocking instance2 = constructor.newInstance((Object[]) null);
(ThreadSafeDoubleCheckLocking) constructor.newInstance(null);
} }
} }
\ No newline at end of file
...@@ -29,7 +29,7 @@ package com.iluwatar.singleton; ...@@ -29,7 +29,7 @@ package com.iluwatar.singleton;
* @author Jeroen Meulemeester * @author Jeroen Meulemeester
*/ */
public class ThreadSafeLazyLoadedIvoryTowerTest public class ThreadSafeLazyLoadedIvoryTowerTest
extends SingletonTest<ThreadSafeLazyLoadedIvoryTower> { extends SingletonTest<ThreadSafeLazyLoadedIvoryTower> {
/** /**
* Create a new singleton test instance using the given 'getInstance' method. * Create a new singleton test instance using the given 'getInstance' method.
......
...@@ -19,9 +19,9 @@ Say, you are building a war game with hundreds, or maybe even thousands of playe ...@@ -19,9 +19,9 @@ Say, you are building a war game with hundreds, or maybe even thousands of playe
```java ```java
public void handleMeLee(Unit units[], int numUnits) { public void handleMeLee(Unit units[], int numUnits) {
for (int a = 0; a < numUnits - 1; a++) for (var a = 0; a < numUnits - 1; a++)
{ {
for (int b = a + 1; b < numUnits; b++) for (var b = a + 1; b < numUnits; b++)
{ {
if (units[a].position() == units[b].position()) if (units[a].position() == units[b].position())
{ {
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Random; import java.util.Random;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -62,58 +60,46 @@ import org.slf4j.LoggerFactory; ...@@ -62,58 +60,46 @@ import org.slf4j.LoggerFactory;
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
static void noSpatialPartition(int height, int width, static void noSpatialPartition(int numOfMovements, Hashtable<Integer, Bubble> bubbles) {
int numOfMovements, Hashtable<Integer, Bubble> bubbles) { //all bubbles have to be checked for collision for all bubbles
ArrayList<Point> bubblesToCheck = new ArrayList<Point>(); var bubblesToCheck = bubbles.values();
for (Enumeration<Integer> e = bubbles.keys(); e.hasMoreElements(); ) {
bubblesToCheck.add(bubbles
.get(e.nextElement())); //all bubbles have to be checked for collision for all bubbles
}
//will run numOfMovement times or till all bubbles have popped //will run numOfMovement times or till all bubbles have popped
while (numOfMovements > 0 && !bubbles.isEmpty()) { while (numOfMovements > 0 && !bubbles.isEmpty()) {
for (Enumeration<Integer> e = bubbles.keys(); e.hasMoreElements(); ) { bubbles.forEach((i, bubble) -> {
Integer i = e.nextElement();
// bubble moves, new position gets updated // bubble moves, new position gets updated
// and collisions are checked with all bubbles in bubblesToCheck // and collisions are checked with all bubbles in bubblesToCheck
bubbles.get(i).move(); bubble.move();
bubbles.replace(i, bubbles.get(i)); bubbles.replace(i, bubble);
bubbles.get(i).handleCollision(bubblesToCheck, bubbles); bubble.handleCollision(bubblesToCheck, bubbles);
} });
numOfMovements--; numOfMovements--;
} }
for (Integer key : bubbles.keySet()) { //bubbles not popped
//bubbles not popped bubbles.keySet().stream().map(key -> "Bubble " + key + " not popped").forEach(LOGGER::info);
LOGGER.info("Bubble " + key + " not popped");
}
} }
static void withSpatialPartition( static void withSpatialPartition(
int height, int width, int numOfMovements, Hashtable<Integer, Bubble> bubbles) { int height, int width, int numOfMovements, Hashtable<Integer, Bubble> bubbles) {
//creating quadtree //creating quadtree
Rect rect = new Rect(width / 2, height / 2, width, height); var rect = new Rect(width / 2, height / 2, width, height);
QuadTree quadTree = new QuadTree(rect, 4); var quadTree = new QuadTree(rect, 4);
//will run numOfMovement times or till all bubbles have popped //will run numOfMovement times or till all bubbles have popped
while (numOfMovements > 0 && !bubbles.isEmpty()) { while (numOfMovements > 0 && !bubbles.isEmpty()) {
//quadtree updated each time //quadtree updated each time
for (Enumeration<Integer> e = bubbles.keys(); e.hasMoreElements(); ) { bubbles.values().forEach(quadTree::insert);
quadTree.insert(bubbles.get(e.nextElement())); bubbles.forEach((i, bubble) -> {
}
for (Enumeration<Integer> e = bubbles.keys(); e.hasMoreElements(); ) {
Integer i = e.nextElement();
//bubble moves, new position gets updated, quadtree used to reduce computations //bubble moves, new position gets updated, quadtree used to reduce computations
bubbles.get(i).move(); bubble.move();
bubbles.replace(i, bubbles.get(i)); bubbles.replace(i, bubble);
SpatialPartitionBubbles sp = new SpatialPartitionBubbles(bubbles, quadTree); var sp = new SpatialPartitionBubbles(bubbles, quadTree);
sp.handleCollisionsUsingQt(bubbles.get(i)); sp.handleCollisionsUsingQt(bubble);
} });
numOfMovements--; numOfMovements--;
} }
for (Integer key : bubbles.keySet()) { //bubbles not popped
//bubbles not popped bubbles.keySet().stream().map(key -> "Bubble " + key + " not popped").forEach(LOGGER::info);
LOGGER.info("Bubble " + key + " not popped");
}
} }
/** /**
...@@ -123,23 +109,23 @@ public class App { ...@@ -123,23 +109,23 @@ public class App {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
Hashtable<Integer, Bubble> bubbles1 = new Hashtable<Integer, Bubble>(); var bubbles1 = new Hashtable<Integer, Bubble>();
Hashtable<Integer, Bubble> bubbles2 = new Hashtable<Integer, Bubble>(); var bubbles2 = new Hashtable<Integer, Bubble>();
Random rand = new Random(); var rand = new Random();
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
Bubble b = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1); var b = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1);
bubbles1.put(i, b); bubbles1.put(i, b);
bubbles2.put(i, b); bubbles2.put(i, b);
LOGGER.info("Bubble " + i + " with radius " + b.radius LOGGER.info("Bubble " + i + " with radius " + b.radius
+ " added at (" + b.coordinateX + "," + b.coordinateY + ")"); + " added at (" + b.coordinateX + "," + b.coordinateY + ")");
} }
long start1 = System.currentTimeMillis(); var start1 = System.currentTimeMillis();
App.noSpatialPartition(300, 300, 20, bubbles1); App.noSpatialPartition(20, bubbles1);
long end1 = System.currentTimeMillis(); var end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis(); var start2 = System.currentTimeMillis();
App.withSpatialPartition(300, 300, 20, bubbles2); App.withSpatialPartition(300, 300, 20, bubbles2);
long end2 = System.currentTimeMillis(); var end2 = System.currentTimeMillis();
LOGGER.info("Without spatial partition takes " + (end1 - start1) + "ms"); LOGGER.info("Without spatial partition takes " + (end1 - start1) + "ms");
LOGGER.info("With spatial partition takes " + (end2 - start2) + "ms"); LOGGER.info("With spatial partition takes " + (end2 - start2) + "ms");
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import java.util.ArrayList; import java.util.Collection;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Random; import java.util.Random;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -64,10 +64,10 @@ public class Bubble extends Point<Bubble> { ...@@ -64,10 +64,10 @@ public class Bubble extends Point<Bubble> {
allBubbles.remove(this.id); allBubbles.remove(this.id);
} }
void handleCollision(ArrayList<Point> bubblesToCheck, Hashtable<Integer, Bubble> allBubbles) { void handleCollision(Collection<? extends Point> toCheck, Hashtable<Integer, Bubble> allBubbles) {
boolean toBePopped = false; //if any other bubble collides with it, made true var toBePopped = false; //if any other bubble collides with it, made true
for (int i = 0; i < bubblesToCheck.size(); i++) { for (var point : toCheck) {
Integer otherId = bubblesToCheck.get(i).id; var otherId = point.id;
if (allBubbles.get(otherId) != null && //the bubble hasn't been popped yet if (allBubbles.get(otherId) != null && //the bubble hasn't been popped yet
this.id != otherId && //the two bubbles are not the same this.id != otherId && //the two bubbles are not the same
this.touches(allBubbles.get(otherId))) { //the bubbles touch this.touches(allBubbles.get(otherId))) { //the bubbles touch
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import java.util.ArrayList; import java.util.Collection;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
...@@ -61,8 +61,8 @@ public abstract class Point<T> { ...@@ -61,8 +61,8 @@ public abstract class Point<T> {
/** /**
* handling interactions/collisions with other objects. * handling interactions/collisions with other objects.
* *
* @param pointsToCheck contains the objects which need to be checked * @param toCheck contains the objects which need to be checked
* @param allPoints contains hashtable of all points on field at this time * @param all contains hashtable of all points on field at this time
*/ */
abstract void handleCollision(ArrayList<Point> pointsToCheck, Hashtable<Integer, T> allPoints); abstract void handleCollision(Collection<? extends Point> toCheck, Hashtable<Integer, T> all);
} }
...@@ -23,8 +23,7 @@ ...@@ -23,8 +23,7 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import java.util.ArrayList; import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
...@@ -47,7 +46,7 @@ public class QuadTree { ...@@ -47,7 +46,7 @@ public class QuadTree {
this.boundary = boundary; this.boundary = boundary;
this.capacity = capacity; this.capacity = capacity;
this.divided = false; this.divided = false;
this.points = new Hashtable<Integer, Point>(); this.points = new Hashtable<>();
this.northwest = null; this.northwest = null;
this.northeast = null; this.northeast = null;
this.southwest = null; this.southwest = null;
...@@ -76,30 +75,29 @@ public class QuadTree { ...@@ -76,30 +75,29 @@ public class QuadTree {
} }
void divide() { void divide() {
double x = this.boundary.coordinateX; var x = this.boundary.coordinateX;
double y = this.boundary.coordinateY; var y = this.boundary.coordinateY;
double width = this.boundary.width; var width = this.boundary.width;
double height = this.boundary.height; var height = this.boundary.height;
Rect nw = new Rect(x - width / 4, y + height / 4, width / 2, height / 2); var nw = new Rect(x - width / 4, y + height / 4, width / 2, height / 2);
this.northwest = new QuadTree(nw, this.capacity); this.northwest = new QuadTree(nw, this.capacity);
Rect ne = new Rect(x + width / 4, y + height / 4, width / 2, height / 2); var ne = new Rect(x + width / 4, y + height / 4, width / 2, height / 2);
this.northeast = new QuadTree(ne, this.capacity); this.northeast = new QuadTree(ne, this.capacity);
Rect sw = new Rect(x - width / 4, y - height / 4, width / 2, height / 2); var sw = new Rect(x - width / 4, y - height / 4, width / 2, height / 2);
this.southwest = new QuadTree(sw, this.capacity); this.southwest = new QuadTree(sw, this.capacity);
Rect se = new Rect(x + width / 4, y - height / 4, width / 2, height / 2); var se = new Rect(x + width / 4, y - height / 4, width / 2, height / 2);
this.southeast = new QuadTree(se, this.capacity); this.southeast = new QuadTree(se, this.capacity);
this.divided = true; this.divided = true;
} }
ArrayList<Point> query(Rect r, ArrayList<Point> relevantPoints) { Collection<Point> query(Rect r, Collection<Point> relevantPoints) {
//could also be a circle instead of a rectangle //could also be a circle instead of a rectangle
if (this.boundary.intersects(r)) { if (this.boundary.intersects(r)) {
for (Enumeration<Integer> e = this.points.keys(); e.hasMoreElements(); ) { this.points
Integer i = e.nextElement(); .values()
if (r.contains(this.points.get(i))) { .stream()
relevantPoints.add(this.points.get(i)); .filter(r::contains)
} .forEach(relevantPoints::add);
}
if (this.divided) { if (this.divided) {
this.northwest.query(r, relevantPoints); this.northwest.query(r, relevantPoints);
this.northeast.query(r, relevantPoints); this.northeast.query(r, relevantPoints);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
...@@ -44,8 +45,8 @@ public class SpatialPartitionBubbles extends SpatialPartitionGeneric<Bubble> { ...@@ -44,8 +45,8 @@ public class SpatialPartitionBubbles extends SpatialPartitionGeneric<Bubble> {
void handleCollisionsUsingQt(Bubble b) { void handleCollisionsUsingQt(Bubble b) {
// finding points within area of a square drawn with centre same as // finding points within area of a square drawn with centre same as
// centre of bubble and length = radius of bubble // centre of bubble and length = radius of bubble
Rect rect = new Rect(b.coordinateX, b.coordinateY, 2 * b.radius, 2 * b.radius); var rect = new Rect(b.coordinateX, b.coordinateY, 2 * b.radius, 2 * b.radius);
ArrayList<Point> quadTreeQueryResult = new ArrayList<Point>(); var quadTreeQueryResult = new ArrayList<Point>();
this.quadTree.query(rect, quadTreeQueryResult); this.quadTree.query(rect, quadTreeQueryResult);
//handling these collisions //handling these collisions
b.handleCollision(quadTreeQueryResult, this.bubbles); b.handleCollision(quadTreeQueryResult, this.bubbles);
......
...@@ -23,62 +23,71 @@ ...@@ -23,62 +23,71 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
* Testing methods in Bubble class. * Testing methods in Bubble class.
*/ */
class BubbleTest { class BubbleTest {
@Test @Test
void moveTest() { void moveTest() {
Bubble b = new Bubble(10,10,1,2); var b = new Bubble(10, 10, 1, 2);
int initialX = b.coordinateX; var initialX = b.coordinateX;
int initialY = b.coordinateY; var initialY = b.coordinateY;
b.move(); b.move();
//change in x and y < |2| //change in x and y < |2|
assertTrue((b.coordinateX - initialX < 2 && b.coordinateX - initialX > -2) && (b.coordinateY - initialY < 2 && b.coordinateY - initialY > -2)); assertTrue(b.coordinateX - initialX < 2 && b.coordinateX - initialX > -2);
assertTrue(b.coordinateY - initialY < 2 && b.coordinateY - initialY > -2);
} }
@Test @Test
void touchesTest() { void touchesTest() {
Bubble b1 = new Bubble(0,0,1,2); var b1 = new Bubble(0, 0, 1, 2);
Bubble b2 = new Bubble(1,1,2,1); var b2 = new Bubble(1, 1, 2, 1);
Bubble b3 = new Bubble(10,10,3,1); var b3 = new Bubble(10, 10, 3, 1);
//b1 touches b2 but not b3 //b1 touches b2 but not b3
assertTrue(b1.touches(b2) && !b1.touches(b3)); assertTrue(b1.touches(b2));
assertFalse(b1.touches(b3));
} }
@Test @Test
void popTest() { void popTest() {
Bubble b1 = new Bubble(10,10,1,2); var b1 = new Bubble(10, 10, 1, 2);
Bubble b2 = new Bubble(0,0,2,2); var b2 = new Bubble(0, 0, 2, 2);
Hashtable<Integer, Bubble> bubbles = new Hashtable<Integer, Bubble>(); var bubbles = new Hashtable<Integer, Bubble>();
bubbles.put(1, b1); bubbles.put(1, b1);
bubbles.put(2, b2); bubbles.put(2, b2);
b1.pop(bubbles); b1.pop(bubbles);
//after popping, bubble no longer in hashtable containing all bubbles //after popping, bubble no longer in hashtable containing all bubbles
assertTrue(bubbles.get(1) == null && bubbles.get(2) != null); assertNull(bubbles.get(1));
assertNotNull(bubbles.get(2));
} }
@Test @Test
void handleCollisionTest() { void handleCollisionTest() {
Bubble b1 = new Bubble(0,0,1,2); var b1 = new Bubble(0, 0, 1, 2);
Bubble b2 = new Bubble(1,1,2,1); var b2 = new Bubble(1, 1, 2, 1);
Bubble b3 = new Bubble(10,10,3,1); var b3 = new Bubble(10, 10, 3, 1);
Hashtable<Integer, Bubble> bubbles = new Hashtable<Integer, Bubble>(); var bubbles = new Hashtable<Integer, Bubble>();
bubbles.put(1, b1); bubbles.put(1, b1);
bubbles.put(2, b2); bubbles.put(2, b2);
bubbles.put(3, b3); bubbles.put(3, b3);
ArrayList<Point> bubblesToCheck = new ArrayList<Point>(); var bubblesToCheck = new ArrayList<Point>();
bubblesToCheck.add(b2); bubblesToCheck.add(b2);
bubblesToCheck.add(b3); bubblesToCheck.add(b3);
b1.handleCollision(bubblesToCheck, bubbles); b1.handleCollision(bubblesToCheck, bubbles);
//b1 touches b2 and not b3, so b1, b2 will be popped //b1 touches b2 and not b3, so b1, b2 will be popped
assertTrue(bubbles.get(1) == null && bubbles.get(2) == null && bubbles.get(3) != null); assertNull(bubbles.get(1));
assertNull(bubbles.get(2));
assertNotNull(bubbles.get(3));
} }
} }
...@@ -23,12 +23,13 @@ ...@@ -23,12 +23,13 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
...@@ -39,41 +40,34 @@ class QuadTreeTest { ...@@ -39,41 +40,34 @@ class QuadTreeTest {
@Test @Test
void queryTest() { void queryTest() {
ArrayList<Point> points = new ArrayList<Point>(); var points = new ArrayList<Point>();
Random rand = new Random(); var rand = new Random();
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
Bubble p = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1); var p = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1);
points.add(p); points.add(p);
} }
Rect field = new Rect(150,150,300,300); //size of field var field = new Rect(150, 150, 300, 300); //size of field
Rect queryRange = new Rect(70,130,100,100); //result = all points lying in this rectangle var queryRange = new Rect(70, 130, 100, 100); //result = all points lying in this rectangle
//points found in the query range using quadtree and normal method is same //points found in the query range using quadtree and normal method is same
assertTrue(QuadTreeTest.quadTreeTest(points, field, queryRange).equals(QuadTreeTest.verify(points, queryRange))); var points1 = QuadTreeTest.quadTreeTest(points, field, queryRange);
var points2 = QuadTreeTest.verify(points, queryRange);
assertEquals(points1, points2);
} }
static Hashtable<Integer, Point> quadTreeTest(ArrayList<Point> points, Rect field, Rect queryRange) { static Hashtable<Integer, Point> quadTreeTest(Collection<Point> points, Rect field, Rect queryRange) {
//creating quadtree and inserting all points //creating quadtree and inserting all points
QuadTree qTree = new QuadTree(queryRange, 4); var qTree = new QuadTree(queryRange, 4);
for (int i = 0; i < points.size(); i++) { points.forEach(qTree::insert);
qTree.insert(points.get(i));
}
ArrayList<Point> queryResult = qTree.query(field, new ArrayList<Point>()); return qTree
Hashtable<Integer, Point> result = new Hashtable<Integer, Point>(); .query(field, new ArrayList<>())
for (int i = 0; i < queryResult.size(); i++) { .stream()
Point p = queryResult.get(i); .collect(Collectors.toMap(p -> p.id, p -> p, (a, b) -> b, Hashtable::new));
result.put(p.id, p);
}
return result;
} }
static Hashtable<Integer, Point> verify(ArrayList<Point> points, Rect queryRange) { static Hashtable<Integer, Point> verify(Collection<Point> points, Rect queryRange) {
Hashtable<Integer, Point> result = new Hashtable<Integer, Point>(); return points.stream()
for (int i = 0; i < points.size(); i++) { .filter(queryRange::contains)
if (queryRange.contains(points.get(i))) { .collect(Collectors.toMap(point -> point.id, point -> point, (a, b) -> b, Hashtable::new));
result.put(points.get(i).id, points.get(i));
}
}
return result;
} }
} }
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
...@@ -34,19 +36,21 @@ class RectTest { ...@@ -34,19 +36,21 @@ class RectTest {
@Test @Test
void containsTest() { void containsTest() {
Rect r = new Rect(10,10,20,20); var r = new Rect(10, 10, 20, 20);
Bubble b1 = new Bubble(2,2,1,1); var b1 = new Bubble(2, 2, 1, 1);
Bubble b2 = new Bubble(30,30,2,1); var b2 = new Bubble(30, 30, 2, 1);
//r contains b1 and not b2 //r contains b1 and not b2
assertTrue(r.contains(b1) && !r.contains(b2)); assertTrue(r.contains(b1));
assertFalse(r.contains(b2));
} }
@Test @Test
void intersectsTest() { void intersectsTest() {
Rect r1 = new Rect(10,10,20,20); var r1 = new Rect(10, 10, 20, 20);
Rect r2 = new Rect(15,15,20,20); var r2 = new Rect(15, 15, 20, 20);
Rect r3 = new Rect(50,50,20,20); var r3 = new Rect(50, 50, 20, 20);
//r1 intersects r2 and not r3 //r1 intersects r2 and not r3
assertTrue(r1.intersects(r2) && !r1.intersects(r3)); assertTrue(r1.intersects(r2));
assertFalse(r1.intersects(r3));
} }
} }
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
package com.iluwatar.spatialpartition; package com.iluwatar.spatialpartition;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.util.Hashtable; import java.util.Hashtable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -35,24 +37,27 @@ class SpatialPartitionBubblesTest { ...@@ -35,24 +37,27 @@ class SpatialPartitionBubblesTest {
@Test @Test
void handleCollisionsUsingQtTest() { void handleCollisionsUsingQtTest() {
Bubble b1 = new Bubble(10,10,1,3); var b1 = new Bubble(10, 10, 1, 3);
Bubble b2 = new Bubble(5,5,2,1); var b2 = new Bubble(5, 5, 2, 1);
Bubble b3 = new Bubble(9,9,3,1); var b3 = new Bubble(9, 9, 3, 1);
Bubble b4 = new Bubble(8,8,4,2); var b4 = new Bubble(8, 8, 4, 2);
Hashtable<Integer, Bubble> bubbles = new Hashtable<Integer, Bubble>(); var bubbles = new Hashtable<Integer, Bubble>();
bubbles.put(1, b1); bubbles.put(1, b1);
bubbles.put(2, b2); bubbles.put(2, b2);
bubbles.put(3, b3); bubbles.put(3, b3);
bubbles.put(4, b4); bubbles.put(4, b4);
Rect r = new Rect(10,10,20,20); var r = new Rect(10, 10, 20, 20);
QuadTree qt = new QuadTree(r,4); var qt = new QuadTree(r, 4);
qt.insert(b1); qt.insert(b1);
qt.insert(b2); qt.insert(b2);
qt.insert(b3); qt.insert(b3);
qt.insert(b4); qt.insert(b4);
SpatialPartitionBubbles sp = new SpatialPartitionBubbles(bubbles, qt); var sp = new SpatialPartitionBubbles(bubbles, qt);
sp.handleCollisionsUsingQt(b1); sp.handleCollisionsUsingQt(b1);
//b1 touches b3 and b4 but not b2 - so b1,b3,b4 get popped //b1 touches b3 and b4 but not b2 - so b1,b3,b4 get popped
assertTrue(bubbles.get(1) == null && bubbles.get(2) != null && bubbles.get(3) == null && bubbles.get(4) == null); assertNull(bubbles.get(1));
assertNotNull(bubbles.get(2));
assertNull(bubbles.get(3));
assertNull(bubbles.get(4));
} }
} }
...@@ -100,24 +100,24 @@ public class MassGreaterThanSelector extends AbstractSelector<Creature> { ...@@ -100,24 +100,24 @@ public class MassGreaterThanSelector extends AbstractSelector<Creature> {
With these building blocks in place, we can perform a search for red creatures as follows: With these building blocks in place, we can perform a search for red creatures as follows:
```java ```java
List<Creature> redCreatures = creatures.stream().filter(new ColorSelector(Color.RED)) var redCreatures = creatures.stream().filter(new ColorSelector(Color.RED))
.collect(Collectors.toList()); .collect(Collectors.toList());
``` ```
But we could also use our parameterized selector like this: But we could also use our parameterized selector like this:
```java ```java
List<Creature> heavyCreatures = creatures.stream().filter(new MassGreaterThanSelector(500.0) var heavyCreatures = creatures.stream().filter(new MassGreaterThanSelector(500.0)
.collect(Collectors.toList()); .collect(Collectors.toList());
``` ```
Our third option is to combine multiple selectors together. Performing a search for special creatures (defined as red, flying, and not small) could be done as follows: Our third option is to combine multiple selectors together. Performing a search for special creatures (defined as red, flying, and not small) could be done as follows:
```java ```java
AbstractSelector specialCreaturesSelector = var specialCreaturesSelector =
new ColorSelector(Color.RED).and(new MovementSelector(Movement.FLYING)).and(new SizeSelector(Size.SMALL).not()); new ColorSelector(Color.RED).and(new MovementSelector(Movement.FLYING)).and(new SizeSelector(Size.SMALL).not());
List<Creature> specialCreatures = creatures.stream().filter(specialCreaturesSelector) var specialCreatures = creatures.stream().filter(specialCreaturesSelector)
.collect(Collectors.toList()); .collect(Collectors.toList());
``` ```
......
...@@ -32,14 +32,14 @@ import com.iluwatar.specification.creature.Shark; ...@@ -32,14 +32,14 @@ import com.iluwatar.specification.creature.Shark;
import com.iluwatar.specification.creature.Troll; import com.iluwatar.specification.creature.Troll;
import com.iluwatar.specification.property.Color; import com.iluwatar.specification.property.Color;
import com.iluwatar.specification.property.Movement; import com.iluwatar.specification.property.Movement;
import com.iluwatar.specification.selector.AbstractSelector;
import com.iluwatar.specification.selector.ColorSelector; import com.iluwatar.specification.selector.ColorSelector;
import com.iluwatar.specification.selector.MassEqualSelector; import com.iluwatar.specification.selector.MassEqualSelector;
import com.iluwatar.specification.selector.MassGreaterThanSelector; import com.iluwatar.specification.selector.MassGreaterThanSelector;
import com.iluwatar.specification.selector.MassSmallerThanOrEqSelector; import com.iluwatar.specification.selector.MassSmallerThanOrEqSelector;
import com.iluwatar.specification.selector.MovementSelector; import com.iluwatar.specification.selector.MovementSelector;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.Objects;
import java.util.function.Predicate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -63,57 +63,47 @@ public class App { ...@@ -63,57 +63,47 @@ public class App {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
// initialize creatures list // initialize creatures list
List<Creature> creatures = List.of(new Goblin(), new Octopus(), new Dragon(), new Shark(), var creatures = List.of(
new Troll(), new KillerBee()); new Goblin(),
new Octopus(),
new Dragon(),
new Shark(),
new Troll(),
new KillerBee()
);
// so-called "hard-coded" specification // so-called "hard-coded" specification
LOGGER.info("Demonstrating hard-coded specification :"); LOGGER.info("Demonstrating hard-coded specification :");
// find all walking creatures // find all walking creatures
LOGGER.info("Find all walking creatures"); LOGGER.info("Find all walking creatures");
List<Creature> walkingCreatures = print(creatures, new MovementSelector(Movement.WALKING));
creatures.stream().filter(new MovementSelector(Movement.WALKING))
.collect(Collectors.toList());
walkingCreatures.forEach(c -> LOGGER.info(c.toString()));
// find all dark creatures // find all dark creatures
LOGGER.info("Find all dark creatures"); LOGGER.info("Find all dark creatures");
List<Creature> darkCreatures = print(creatures, new ColorSelector(Color.DARK));
creatures.stream().filter(new ColorSelector(Color.DARK)).collect(Collectors.toList());
darkCreatures.forEach(c -> LOGGER.info(c.toString()));
LOGGER.info("\n"); LOGGER.info("\n");
// so-called "parameterized" specification // so-called "parameterized" specification
LOGGER.info("Demonstrating parameterized specification :"); LOGGER.info("Demonstrating parameterized specification :");
// find all creatures heavier than 500kg // find all creatures heavier than 500kg
LOGGER.info("Find all creatures heavier than 600kg"); LOGGER.info("Find all creatures heavier than 600kg");
List<Creature> heavyCreatures = print(creatures, new MassGreaterThanSelector(600.0));
creatures.stream().filter(new MassGreaterThanSelector(600.0))
.collect(Collectors.toList());
heavyCreatures.forEach(c -> LOGGER.info(c.toString()));
// find all creatures heavier than 500kg // find all creatures heavier than 500kg
LOGGER.info("Find all creatures lighter than or weighing exactly 500kg"); LOGGER.info("Find all creatures lighter than or weighing exactly 500kg");
List<Creature> lightCreatures = print(creatures, new MassSmallerThanOrEqSelector(500.0));
creatures.stream().filter(new MassSmallerThanOrEqSelector(500.0))
.collect(Collectors.toList());
lightCreatures.forEach(c -> LOGGER.info(c.toString()));
LOGGER.info("\n"); LOGGER.info("\n");
// so-called "composite" specification // so-called "composite" specification
LOGGER.info("Demonstrating composite specification :"); LOGGER.info("Demonstrating composite specification :");
// find all red and flying creatures // find all red and flying creatures
LOGGER.info("Find all red and flying creatures"); LOGGER.info("Find all red and flying creatures");
List<Creature> redAndFlyingCreatures = var redAndFlying = new ColorSelector(Color.RED).and(new MovementSelector(Movement.FLYING));
creatures.stream() print(creatures, redAndFlying);
.filter(new ColorSelector(Color.RED).and(new MovementSelector(Movement.FLYING)))
.collect(Collectors.toList());
redAndFlyingCreatures.forEach(c -> LOGGER.info(c.toString()));
// find all creatures dark or red, non-swimming, and heavier than or equal to 400kg // find all creatures dark or red, non-swimming, and heavier than or equal to 400kg
LOGGER.info("Find all scary creatures"); LOGGER.info("Find all scary creatures");
AbstractSelector<Creature> scaryCreaturesSelector = new ColorSelector(Color.DARK) var scaryCreaturesSelector = new ColorSelector(Color.DARK)
.or(new ColorSelector(Color.RED)).and(new MovementSelector(Movement.SWIMMING).not()) .or(new ColorSelector(Color.RED)).and(new MovementSelector(Movement.SWIMMING).not())
.and(new MassGreaterThanSelector(400.0).or(new MassEqualSelector(400.0))); .and(new MassGreaterThanSelector(400.0).or(new MassEqualSelector(400.0)));
List<Creature> scaryCreatures = print(creatures, scaryCreaturesSelector);
creatures.stream() }
.filter(scaryCreaturesSelector)
.collect(Collectors.toList()); private static void print(List<? extends Creature> creatures, Predicate<Creature> selector) {
scaryCreatures.forEach(c -> LOGGER.info(c.toString())); creatures.stream().filter(selector).map(Objects::toString).forEach(LOGGER::info);
} }
} }
...@@ -32,7 +32,6 @@ public class AppTest { ...@@ -32,7 +32,6 @@ public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -83,27 +83,24 @@ public class CreatureTest { ...@@ -83,27 +83,24 @@ public class CreatureTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("dataProvider") @MethodSource("dataProvider")
public void testGetColor(Creature testedCreature, String name, Size size, Movement movement, public void testGetColor(Creature testedCreature, String name, Size size, Movement movement,
Color color) { Color color) {
assertEquals(color, testedCreature.getColor()); assertEquals(color, testedCreature.getColor());
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("dataProvider") @MethodSource("dataProvider")
public void testGetMass(Creature testedCreature, String name, Size size, Movement movement, public void testGetMass(Creature testedCreature, String name, Size size, Movement movement,
Color color, Mass mass) { Color color, Mass mass) {
assertEquals(mass, testedCreature.getMass()); assertEquals(mass, testedCreature.getMass());
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("dataProvider") @MethodSource("dataProvider")
public void testToString(Creature testedCreature, String name, Size size, Movement movement, public void testToString(Creature testedCreature, String name, Size size, Movement movement,
Color color, Mass mass) { Color color, Mass mass) {
final String toString = testedCreature.toString(); final var toString = testedCreature.toString();
assertNotNull(toString); assertNotNull(toString);
assertEquals( assertEquals(String
String.format("%s [size=%s, movement=%s, color=%s, mass=%s]", name, size, movement, color, .format("%s [size=%s, movement=%s, color=%s, mass=%s]", name, size, movement, color, mass), toString);
mass),
toString
);
} }
} }
\ No newline at end of file
...@@ -44,13 +44,13 @@ public class ColorSelectorTest { ...@@ -44,13 +44,13 @@ public class ColorSelectorTest {
*/ */
@Test @Test
public void testColor() { public void testColor() {
final Creature greenCreature = mock(Creature.class); final var greenCreature = mock(Creature.class);
when(greenCreature.getColor()).thenReturn(Color.GREEN); when(greenCreature.getColor()).thenReturn(Color.GREEN);
final Creature redCreature = mock(Creature.class); final var redCreature = mock(Creature.class);
when(redCreature.getColor()).thenReturn(Color.RED); when(redCreature.getColor()).thenReturn(Color.RED);
final ColorSelector greenSelector = new ColorSelector(Color.GREEN); final var greenSelector = new ColorSelector(Color.GREEN);
assertTrue(greenSelector.test(greenCreature)); assertTrue(greenSelector.test(greenCreature));
assertFalse(greenSelector.test(redCreature)); assertFalse(greenSelector.test(redCreature));
......
...@@ -40,16 +40,16 @@ public class CompositeSelectorsTest { ...@@ -40,16 +40,16 @@ public class CompositeSelectorsTest {
*/ */
@Test @Test
public void testAndComposition() { public void testAndComposition() {
final Creature swimmingHeavyCreature = mock(Creature.class); final var swimmingHeavyCreature = mock(Creature.class);
when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0)); when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0));
final Creature swimmingLightCreature = mock(Creature.class); final var swimmingLightCreature = mock(Creature.class);
when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0)); when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0));
final AbstractSelector<Creature> lightAndSwimmingSelector = new MassSmallerThanOrEqSelector( final var lightAndSwimmingSelector = new MassSmallerThanOrEqSelector(50.0)
50.0).and(new MovementSelector(Movement.SWIMMING)); .and(new MovementSelector(Movement.SWIMMING));
assertFalse(lightAndSwimmingSelector.test(swimmingHeavyCreature)); assertFalse(lightAndSwimmingSelector.test(swimmingHeavyCreature));
assertTrue(lightAndSwimmingSelector.test(swimmingLightCreature)); assertTrue(lightAndSwimmingSelector.test(swimmingLightCreature));
} }
...@@ -59,15 +59,15 @@ public class CompositeSelectorsTest { ...@@ -59,15 +59,15 @@ public class CompositeSelectorsTest {
*/ */
@Test @Test
public void testOrComposition() { public void testOrComposition() {
final Creature swimmingHeavyCreature = mock(Creature.class); final var swimmingHeavyCreature = mock(Creature.class);
when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0)); when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0));
final Creature swimmingLightCreature = mock(Creature.class); final var swimmingLightCreature = mock(Creature.class);
when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0)); when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0));
final AbstractSelector<Creature> lightOrSwimmingSelector = new MassSmallerThanOrEqSelector(50.0) final var lightOrSwimmingSelector = new MassSmallerThanOrEqSelector(50.0)
.or(new MovementSelector(Movement.SWIMMING)); .or(new MovementSelector(Movement.SWIMMING));
assertTrue(lightOrSwimmingSelector.test(swimmingHeavyCreature)); assertTrue(lightOrSwimmingSelector.test(swimmingHeavyCreature));
assertTrue(lightOrSwimmingSelector.test(swimmingLightCreature)); assertTrue(lightOrSwimmingSelector.test(swimmingLightCreature));
...@@ -78,15 +78,15 @@ public class CompositeSelectorsTest { ...@@ -78,15 +78,15 @@ public class CompositeSelectorsTest {
*/ */
@Test @Test
public void testNotComposition() { public void testNotComposition() {
final Creature swimmingHeavyCreature = mock(Creature.class); final var swimmingHeavyCreature = mock(Creature.class);
when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingHeavyCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0)); when(swimmingHeavyCreature.getMass()).thenReturn(new Mass(100.0));
final Creature swimmingLightCreature = mock(Creature.class); final var swimmingLightCreature = mock(Creature.class);
when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingLightCreature.getMovement()).thenReturn(Movement.SWIMMING);
when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0)); when(swimmingLightCreature.getMass()).thenReturn(new Mass(25.0));
final AbstractSelector<Creature> heavySelector = new MassSmallerThanOrEqSelector(50.0).not(); final var heavySelector = new MassSmallerThanOrEqSelector(50.0).not();
assertTrue(heavySelector.test(swimmingHeavyCreature)); assertTrue(heavySelector.test(swimmingHeavyCreature));
assertFalse(heavySelector.test(swimmingLightCreature)); assertFalse(heavySelector.test(swimmingLightCreature));
} }
......
...@@ -39,13 +39,13 @@ public class MassSelectorTest { ...@@ -39,13 +39,13 @@ public class MassSelectorTest {
*/ */
@Test @Test
public void testMass() { public void testMass() {
final Creature lightCreature = mock(Creature.class); final var lightCreature = mock(Creature.class);
when(lightCreature.getMass()).thenReturn(new Mass(50.0)); when(lightCreature.getMass()).thenReturn(new Mass(50.0));
final Creature heavyCreature = mock(Creature.class); final var heavyCreature = mock(Creature.class);
when(heavyCreature.getMass()).thenReturn(new Mass(2500.0)); when(heavyCreature.getMass()).thenReturn(new Mass(2500.0));
final MassSmallerThanOrEqSelector lightSelector = new MassSmallerThanOrEqSelector(500.0); final var lightSelector = new MassSmallerThanOrEqSelector(500.0);
assertTrue(lightSelector.test(lightCreature)); assertTrue(lightSelector.test(lightCreature));
assertFalse(lightSelector.test(heavyCreature)); assertFalse(lightSelector.test(heavyCreature));
} }
......
...@@ -44,13 +44,13 @@ public class MovementSelectorTest { ...@@ -44,13 +44,13 @@ public class MovementSelectorTest {
*/ */
@Test @Test
public void testMovement() { public void testMovement() {
final Creature swimmingCreature = mock(Creature.class); final var swimmingCreature = mock(Creature.class);
when(swimmingCreature.getMovement()).thenReturn(Movement.SWIMMING); when(swimmingCreature.getMovement()).thenReturn(Movement.SWIMMING);
final Creature flyingCreature = mock(Creature.class); final var flyingCreature = mock(Creature.class);
when(flyingCreature.getMovement()).thenReturn(Movement.FLYING); when(flyingCreature.getMovement()).thenReturn(Movement.FLYING);
final MovementSelector swimmingSelector = new MovementSelector(Movement.SWIMMING); final var swimmingSelector = new MovementSelector(Movement.SWIMMING);
assertTrue(swimmingSelector.test(swimmingCreature)); assertTrue(swimmingSelector.test(swimmingCreature));
assertFalse(swimmingSelector.test(flyingCreature)); assertFalse(swimmingSelector.test(flyingCreature));
......
...@@ -44,13 +44,13 @@ public class SizeSelectorTest { ...@@ -44,13 +44,13 @@ public class SizeSelectorTest {
*/ */
@Test @Test
public void testMovement() { public void testMovement() {
final Creature normalCreature = mock(Creature.class); final var normalCreature = mock(Creature.class);
when(normalCreature.getSize()).thenReturn(Size.NORMAL); when(normalCreature.getSize()).thenReturn(Size.NORMAL);
final Creature smallCreature = mock(Creature.class); final var smallCreature = mock(Creature.class);
when(smallCreature.getSize()).thenReturn(Size.SMALL); when(smallCreature.getSize()).thenReturn(Size.SMALL);
final SizeSelector normalSelector = new SizeSelector(Size.NORMAL); final var normalSelector = new SizeSelector(Size.NORMAL);
assertTrue(normalSelector.test(normalCreature)); assertTrue(normalSelector.test(normalCreature));
assertFalse(normalSelector.test(smallCreature)); assertFalse(normalSelector.test(smallCreature));
} }
......
...@@ -26,15 +26,12 @@ package com.iluwatar.state; ...@@ -26,15 +26,12 @@ package com.iluwatar.state;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
*
* Application test * Application test
*
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -23,20 +23,19 @@ ...@@ -23,20 +23,19 @@
package com.iluwatar.state; package com.iluwatar.state;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.AppenderBase;
import java.util.LinkedList;
import java.util.List;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/** /**
* Date: 12/29/15 - 8:27 PM * Date: 12/29/15 - 8:27 PM
* *
...@@ -62,27 +61,27 @@ public class MammothTest { ...@@ -62,27 +61,27 @@ public class MammothTest {
*/ */
@Test @Test
public void testTimePasses() { public void testTimePasses() {
final Mammoth mammoth = new Mammoth(); final var mammoth = new Mammoth();
mammoth.observe(); mammoth.observe();
assertEquals("The mammoth is calm and peaceful.", appender.getLastMessage()); assertEquals("The mammoth is calm and peaceful.", appender.getLastMessage());
assertEquals(1 , appender.getLogSize()); assertEquals(1, appender.getLogSize());
mammoth.timePasses(); mammoth.timePasses();
assertEquals("The mammoth gets angry!", appender.getLastMessage()); assertEquals("The mammoth gets angry!", appender.getLastMessage());
assertEquals(2 , appender.getLogSize()); assertEquals(2, appender.getLogSize());
mammoth.observe(); mammoth.observe();
assertEquals("The mammoth is furious!", appender.getLastMessage()); assertEquals("The mammoth is furious!", appender.getLastMessage());
assertEquals(3 , appender.getLogSize()); assertEquals(3, appender.getLogSize());
mammoth.timePasses(); mammoth.timePasses();
assertEquals("The mammoth calms down.", appender.getLastMessage()); assertEquals("The mammoth calms down.", appender.getLastMessage());
assertEquals(4 , appender.getLogSize()); assertEquals(4, appender.getLogSize());
mammoth.observe(); mammoth.observe();
assertEquals("The mammoth is calm and peaceful.", appender.getLastMessage()); assertEquals("The mammoth is calm and peaceful.", appender.getLastMessage());
assertEquals(5 , appender.getLogSize()); assertEquals(5, appender.getLogSize());
} }
...@@ -91,7 +90,7 @@ public class MammothTest { ...@@ -91,7 +90,7 @@ public class MammothTest {
*/ */
@Test @Test
public void testToString() { public void testToString() {
final String toString = new Mammoth().toString(); final var toString = new Mammoth().toString();
assertNotNull(toString); assertNotNull(toString);
assertEquals("The mammoth", toString); assertEquals("The mammoth", toString);
} }
......
...@@ -67,21 +67,34 @@ public class App { ...@@ -67,21 +67,34 @@ public class App {
*/ */
public static void main(String[] args) { public static void main(String[] args) {
var warrior = var warrior = CharacterStepBuilder
CharacterStepBuilder.newBuilder().name("Amberjill").fighterClass("Paladin") .newBuilder()
.withWeapon("Sword").noAbilities().build(); .name("Amberjill")
.fighterClass("Paladin")
.withWeapon("Sword")
.noAbilities()
.build();
LOGGER.info(warrior.toString()); LOGGER.info(warrior.toString());
var mage = var mage = CharacterStepBuilder
CharacterStepBuilder.newBuilder().name("Riobard").wizardClass("Sorcerer") .newBuilder()
.withSpell("Fireball").withAbility("Fire Aura").withAbility("Teleport") .name("Riobard")
.noMoreAbilities().build(); .wizardClass("Sorcerer")
.withSpell("Fireball")
.withAbility("Fire Aura")
.withAbility("Teleport")
.noMoreAbilities()
.build();
LOGGER.info(mage.toString()); LOGGER.info(mage.toString());
var thief = var thief = CharacterStepBuilder
CharacterStepBuilder.newBuilder().name("Desmond").fighterClass("Rogue").noWeapon().build(); .newBuilder()
.name("Desmond")
.fighterClass("Rogue")
.noWeapon()
.build();
LOGGER.info(thief.toString()); LOGGER.info(thief.toString());
} }
......
...@@ -91,15 +91,15 @@ public class Character { ...@@ -91,15 +91,15 @@ public class Character {
@Override @Override
public String toString() { public String toString() {
var sb = new StringBuilder(); return new StringBuilder()
sb.append("This is a ") .append("This is a ")
.append(fighterClass != null ? fighterClass : wizardClass) .append(fighterClass != null ? fighterClass : wizardClass)
.append(" named ") .append(" named ")
.append(name) .append(name)
.append(" armed with a ") .append(" armed with a ")
.append(weapon != null ? weapon : spell != null ? spell : "with nothing") .append(weapon != null ? weapon : spell != null ? spell : "with nothing")
.append(abilities != null ? " and wielding " + abilities + " abilities" : "") .append(abilities != null ? " and wielding " + abilities + " abilities" : "")
.append('.'); .append('.')
return sb.toString(); .toString();
} }
} }
...@@ -165,7 +165,7 @@ public final class CharacterStepBuilder { ...@@ -165,7 +165,7 @@ public final class CharacterStepBuilder {
@Override @Override
public Character build() { public Character build() {
Character character = new Character(name); var character = new Character(name);
if (fighterClass != null) { if (fighterClass != null) {
character.setFighterClass(fighterClass); character.setFighterClass(fighterClass);
......
...@@ -26,15 +26,12 @@ package com.iluwatar.stepbuilder; ...@@ -26,15 +26,12 @@ package com.iluwatar.stepbuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
*
* Application test * Application test
*
*/ */
public class AppTest { public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -23,15 +23,13 @@ ...@@ -23,15 +23,13 @@
package com.iluwatar.stepbuilder; package com.iluwatar.stepbuilder;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/** /**
* Date: 12/29/15 - 9:21 PM * Date: 12/29/15 - 9:21 PM
* *
...@@ -44,7 +42,7 @@ public class CharacterStepBuilderTest { ...@@ -44,7 +42,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildWizard() { public void testBuildWizard() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Merlin") .name("Merlin")
.wizardClass("alchemist") .wizardClass("alchemist")
.withSpell("poison") .withSpell("poison")
...@@ -58,7 +56,7 @@ public class CharacterStepBuilderTest { ...@@ -58,7 +56,7 @@ public class CharacterStepBuilderTest {
assertEquals("poison", character.getSpell()); assertEquals("poison", character.getSpell());
assertNotNull(character.toString()); assertNotNull(character.toString());
final List<String> abilities = character.getAbilities(); final var abilities = character.getAbilities();
assertNotNull(abilities); assertNotNull(abilities);
assertEquals(2, abilities.size()); assertEquals(2, abilities.size());
assertTrue(abilities.contains("invisibility")); assertTrue(abilities.contains("invisibility"));
...@@ -72,7 +70,7 @@ public class CharacterStepBuilderTest { ...@@ -72,7 +70,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildPoorWizard() { public void testBuildPoorWizard() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Merlin") .name("Merlin")
.wizardClass("alchemist") .wizardClass("alchemist")
.noSpell() .noSpell()
...@@ -91,7 +89,7 @@ public class CharacterStepBuilderTest { ...@@ -91,7 +89,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildWeakWizard() { public void testBuildWeakWizard() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Merlin") .name("Merlin")
.wizardClass("alchemist") .wizardClass("alchemist")
.withSpell("poison") .withSpell("poison")
...@@ -112,7 +110,7 @@ public class CharacterStepBuilderTest { ...@@ -112,7 +110,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildWarrior() { public void testBuildWarrior() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Cuauhtemoc") .name("Cuauhtemoc")
.fighterClass("aztec") .fighterClass("aztec")
.withWeapon("spear") .withWeapon("spear")
...@@ -126,7 +124,7 @@ public class CharacterStepBuilderTest { ...@@ -126,7 +124,7 @@ public class CharacterStepBuilderTest {
assertEquals("spear", character.getWeapon()); assertEquals("spear", character.getWeapon());
assertNotNull(character.toString()); assertNotNull(character.toString());
final List<String> abilities = character.getAbilities(); final var abilities = character.getAbilities();
assertNotNull(abilities); assertNotNull(abilities);
assertEquals(2, abilities.size()); assertEquals(2, abilities.size());
assertTrue(abilities.contains("speed")); assertTrue(abilities.contains("speed"));
...@@ -140,7 +138,7 @@ public class CharacterStepBuilderTest { ...@@ -140,7 +138,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildPoorWarrior() { public void testBuildPoorWarrior() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Poor warrior") .name("Poor warrior")
.fighterClass("none") .fighterClass("none")
.noWeapon() .noWeapon()
...@@ -160,7 +158,7 @@ public class CharacterStepBuilderTest { ...@@ -160,7 +158,7 @@ public class CharacterStepBuilderTest {
*/ */
@Test @Test
public void testBuildWeakWarrior() { public void testBuildWeakWarrior() {
final Character character = CharacterStepBuilder.newBuilder() final var character = CharacterStepBuilder.newBuilder()
.name("Weak warrior") .name("Weak warrior")
.fighterClass("none") .fighterClass("none")
.withWeapon("Slingshot") .withWeapon("Slingshot")
......
...@@ -32,7 +32,6 @@ public class AppTest { ...@@ -32,7 +32,6 @@ public class AppTest {
@Test @Test
public void test() { public void test() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -41,8 +41,8 @@ public class DragonSlayerTest { ...@@ -41,8 +41,8 @@ public class DragonSlayerTest {
*/ */
@Test @Test
public void testGoToBattle() { public void testGoToBattle() {
final DragonSlayingStrategy strategy = mock(DragonSlayingStrategy.class); final var strategy = mock(DragonSlayingStrategy.class);
final DragonSlayer dragonSlayer = new DragonSlayer(strategy); final var dragonSlayer = new DragonSlayer(strategy);
dragonSlayer.goToBattle(); dragonSlayer.goToBattle();
verify(strategy).execute(); verify(strategy).execute();
...@@ -54,13 +54,13 @@ public class DragonSlayerTest { ...@@ -54,13 +54,13 @@ public class DragonSlayerTest {
*/ */
@Test @Test
public void testChangeStrategy() { public void testChangeStrategy() {
final DragonSlayingStrategy initialStrategy = mock(DragonSlayingStrategy.class); final var initialStrategy = mock(DragonSlayingStrategy.class);
final DragonSlayer dragonSlayer = new DragonSlayer(initialStrategy); final var dragonSlayer = new DragonSlayer(initialStrategy);
dragonSlayer.goToBattle(); dragonSlayer.goToBattle();
verify(initialStrategy).execute(); verify(initialStrategy).execute();
final DragonSlayingStrategy newStrategy = mock(DragonSlayingStrategy.class); final var newStrategy = mock(DragonSlayingStrategy.class);
dragonSlayer.changeStrategy(newStrategy); dragonSlayer.changeStrategy(newStrategy);
dragonSlayer.goToBattle(); dragonSlayer.goToBattle();
......
...@@ -28,11 +28,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; ...@@ -28,11 +28,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.AppenderBase;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
...@@ -53,18 +51,18 @@ public class DragonSlayingStrategyTest { ...@@ -53,18 +51,18 @@ public class DragonSlayingStrategyTest {
*/ */
static Collection<Object[]> dataProvider() { static Collection<Object[]> dataProvider() {
return List.of( return List.of(
new Object[]{ new Object[]{
new MeleeStrategy(), new MeleeStrategy(),
"With your Excalibur you sever the dragon's head!" "With your Excalibur you sever the dragon's head!"
}, },
new Object[]{ new Object[]{
new ProjectileStrategy(), new ProjectileStrategy(),
"You shoot the dragon with the magical crossbow and it falls dead on the ground!" "You shoot the dragon with the magical crossbow and it falls dead on the ground!"
}, },
new Object[]{ new Object[]{
new SpellStrategy(), new SpellStrategy(),
"You cast the spell of disintegration and the dragon vaporizes in a pile of dust!" "You cast the spell of disintegration and the dragon vaporizes in a pile of dust!"
} }
); );
} }
......
...@@ -32,7 +32,6 @@ public class AppTest { ...@@ -32,7 +32,6 @@ public class AppTest {
@Test @Test
public void testMain() { public void testMain() {
String[] args = {}; App.main(new String[]{});
App.main(args);
} }
} }
...@@ -70,8 +70,8 @@ public class GroundDiveTest { ...@@ -70,8 +70,8 @@ public class GroundDiveTest {
public void testActivate() { public void testActivate() {
log.clearLog(); log.clearLog();
var groundDive = new GroundDive(); var groundDive = new GroundDive();
groundDive.activate();; groundDive.activate();
String[] logs = log.getLog().split("\n"); var logs = log.getLog().split("\n");
final var expectedSize = 3; final var expectedSize = 3;
final var log1 = logs[0].split("-")[1].trim() + " -" + logs[0].split("-")[2].trim(); final var log1 = logs[0].split("-")[1].trim() + " -" + logs[0].split("-")[2].trim();
final var expectedLog1 = "Move to ( 0.0, 0.0, -20.0 )"; final var expectedLog1 = "Move to ( 0.0, 0.0, -20.0 )";
......
...@@ -70,8 +70,8 @@ public class SkyLaunchTest { ...@@ -70,8 +70,8 @@ public class SkyLaunchTest {
public void testActivate() { public void testActivate() {
log.clearLog(); log.clearLog();
var skyLaunch = new SkyLaunch(); var skyLaunch = new SkyLaunch();
skyLaunch.activate();; skyLaunch.activate();
String[] logs = log.getLog().split("\n"); var logs = log.getLog().split("\n");
final var expectedSize = 3; final var expectedSize = 3;
final var log1 = getLogContent(logs[0]); final var log1 = getLogContent(logs[0]);
final var expectedLog1 = "Move to ( 0.0, 0.0, 20.0 )"; final var expectedLog1 = "Move to ( 0.0, 0.0, 20.0 )";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册