From eb396217d0018f5aaa0545d0f1c5a31fb8eab423 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 22 Nov 2015 19:40:07 +0100 Subject: [PATCH 001/106] #113 Event Driven Architecture - initial commit includes a simple and advanced example of Event-driven architecture --- event-driven-architecture/index.md | 31 +++++++++++++++ event-driven-architecture/pom.xml | 22 +++++++++++ .../java/com/iluwatar/eda/advanced/App.java | 10 +++++ .../com/iluwatar/eda/advanced/Channel.java | 6 +++ .../iluwatar/eda/advanced/DynamicRouter.java | 6 +++ .../java/com/iluwatar/eda/advanced/Event.java | 7 ++++ .../eda/advanced/EventDispatcher.java | 21 ++++++++++ .../com/iluwatar/eda/advanced/Handler.java | 7 ++++ .../com/iluwatar/eda/advanced/Message.java | 6 +++ .../java/com/iluwatar/eda/simple/App.java | 38 +++++++++++++++++++ .../java/com/iluwatar/eda/simple/Event.java | 15 ++++++++ .../com/iluwatar/eda/simple/EventHandler.java | 15 ++++++++ 12 files changed, 184 insertions(+) create mode 100644 event-driven-architecture/index.md create mode 100644 event-driven-architecture/pom.xml create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java diff --git a/event-driven-architecture/index.md b/event-driven-architecture/index.md new file mode 100644 index 000000000..d5b501c3a --- /dev/null +++ b/event-driven-architecture/index.md @@ -0,0 +1,31 @@ +layout: pattern +title: Event Driven Architecture +folder: event-driven-architecture +permalink: /patterns/event-driven-architecture + + +**Intent:** Send and notify state changes of your objects to other applications using an Event-driven Architecture. + +![alt text](./etc/class_diagram.png "Event Driven Architecture") + +**Applicability:** Use an Event-driven architecture when + +* you want to create a loosely coupled system +* you want to build a more responsive system +* you want a system that is easier to extend + +**Real world examples:** + +* A Loan Application has been accepted/rejected (commercial business). +* A new Rostering Schedule is ready for distribution to all crew (Airline Management System). +* An Illegal Trade Pattern has been detected (Trading Fraud Detection System). +* A simulated car has hits another simulated car (Commercial Racing Game). +* A robot has reached its destination (Real Time Warehouse Management System). +* A HTML message has been received (Web Server). +* A key has been pressed (Text Editor). + +**Credits:** + +* [Event-driven architecture - Wikipedia](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained) +* [Fundamental Components of an Event-Driven Architecture](http://giocc.com/fundamental-components-of-an-event-driven-architecture.html) +* [Real World Applications/Event Driven Applications](https://wiki.haskell.org/Real_World_Applications/Event_Driven_Applications) \ No newline at end of file diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml new file mode 100644 index 000000000..fdea3855f --- /dev/null +++ b/event-driven-architecture/pom.xml @@ -0,0 +1,22 @@ + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.8.0-SNAPSHOT + + + event-driven-architecture + + + + junit + junit + test + + + \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java new file mode 100644 index 000000000..bcd2120d8 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java @@ -0,0 +1,10 @@ +package com.iluwatar.eda.advanced; + +public class App { + + public static void main(String[] args) { + EventDispatcher dispatcher = new EventDispatcher(); + dispatcher.registerChannel(Event.class, new Handler()); + dispatcher.dispatch(new Event()); + } +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java new file mode 100644 index 000000000..a977010c6 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java @@ -0,0 +1,6 @@ +package com.iluwatar.eda.advanced; + + +public interface Channel { + public void dispatch(E message); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java new file mode 100644 index 000000000..f72b79150 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java @@ -0,0 +1,6 @@ +package com.iluwatar.eda.advanced; + +public interface DynamicRouter { + public void registerChannel(Class contentType, Channel channel); + public void dispatch(E content); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java new file mode 100644 index 000000000..8ad48c704 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java @@ -0,0 +1,7 @@ +package com.iluwatar.eda.advanced; + +public class Event implements Message { + public Class getType() { + return getClass(); + } +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java new file mode 100644 index 000000000..def8920c1 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java @@ -0,0 +1,21 @@ +package com.iluwatar.eda.advanced; + +import java.util.HashMap; +import java.util.Map; + +public class EventDispatcher implements DynamicRouter { + private Map, Handler> handlers; + + public EventDispatcher() { + handlers = new HashMap, Handler>(); + } + + public void registerChannel(Class contentType, + Channel channel) { + handlers.put(contentType, (Handler)channel); + } + + public void dispatch(Event content) { + handlers.get(content.getClass()).dispatch(content); + } +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java new file mode 100644 index 000000000..68631b207 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java @@ -0,0 +1,7 @@ +package com.iluwatar.eda.advanced; + +public class Handler implements Channel { + public void dispatch(Event message) { + System.out.println(message.getClass()); + } +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java new file mode 100644 index 000000000..00d335191 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java @@ -0,0 +1,6 @@ +package com.iluwatar.eda.advanced; + + +public interface Message { + public Class getType(); +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java new file mode 100644 index 000000000..1399811bb --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java @@ -0,0 +1,38 @@ +package com.iluwatar.eda.simple; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Event-driven architecture (EDA) is a software architecture pattern promoting + * the production, detection, consumption of, and reaction to events. + *

+ * This main class publishes events to queue. Each event on the queue is consumed + * and handled depending on the type defined in the {@link Event} + */ +public class App { + + public static void main(String args[]) { + + //create a list of events having different types + //add these events to a simple queue + Queue events = new LinkedList(); + events.add(new Event('A', "Hello")); + events.add(new Event('B', "event-driven")); + events.add(new Event('A', "world!")); + + Event e; + + //the event loop will go through the list of events + //and handle each one depending on it's type + while (!events.isEmpty()) { + e = events.remove(); + + //handle events depending on their type + if (e.type == 'A') + EventHandler.handleEventA(e); + if (e.type == 'B') + EventHandler.handleEventB(e); + } + } +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java new file mode 100644 index 000000000..1ba04c303 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java @@ -0,0 +1,15 @@ +package com.iluwatar.eda.simple; + +/** + * The Event class defines the type of event and data related to the event. + */ +public class Event { + + public char type; + public String data; + + public Event(char type, String data){ + this.type = type; + this.data = data; + } +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java new file mode 100644 index 000000000..d911c6c8e --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java @@ -0,0 +1,15 @@ +package com.iluwatar.eda.simple; + +/** + * The {@link EventHandler} class handles performs actions on {@link Event} objects + */ +public class EventHandler { + + public static void handleEventA(Event e){ + System.out.println(e.data); + } + + public static void handleEventB(Event e){ + System.out.println(e.data.toUpperCase()); + } +} From 3ef0921f203fbc022c8081fe717ec0af5587ce77 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 23 Nov 2015 00:02:58 +0100 Subject: [PATCH 002/106] #113 Event Driven Architecture - refactored and moved around some classes --- .../main/java/com/iluwatar/eda/advanced/App.java | 12 ++++++++++-- .../java/com/iluwatar/eda/advanced/Channel.java | 6 ------ .../com/iluwatar/eda/advanced/DynamicRouter.java | 6 ------ .../iluwatar/eda/advanced/EventDispatcher.java | 13 +++++++++---- .../java/com/iluwatar/eda/advanced/Handler.java | 7 ------- .../iluwatar/eda/advanced/{ => events}/Event.java | 4 +++- .../eda/advanced/events/UserCreatedEvent.java | 9 +++++++++ .../eda/advanced/events/UserUpdatedEvent.java | 6 ++++++ .../iluwatar/eda/advanced/framework/Channel.java | 8 ++++++++ .../eda/advanced/framework/DynamicRouter.java | 6 ++++++ .../eda/advanced/{ => framework}/Message.java | 2 +- .../advanced/handler/UserCreatedEventHandler.java | 15 +++++++++++++++ .../advanced/handler/UserUpdatedEventHandler.java | 12 ++++++++++++ 13 files changed, 79 insertions(+), 27 deletions(-) delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java rename event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/{ => events}/Event.java (56%) create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java rename event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/{ => framework}/Message.java (63%) create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java index bcd2120d8..e7b8c01bc 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java @@ -1,10 +1,18 @@ package com.iluwatar.eda.advanced; +import com.iluwatar.eda.advanced.events.Event; +import com.iluwatar.eda.advanced.events.UserCreatedEvent; +import com.iluwatar.eda.advanced.events.UserUpdatedEvent; +import com.iluwatar.eda.advanced.handler.UserCreatedEventHandler; +import com.iluwatar.eda.advanced.handler.UserUpdatedEventHandler; + public class App { public static void main(String[] args) { EventDispatcher dispatcher = new EventDispatcher(); - dispatcher.registerChannel(Event.class, new Handler()); - dispatcher.dispatch(new Event()); + dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); + dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); + dispatcher.dispatch(new UserCreatedEvent()); + dispatcher.dispatch(new UserUpdatedEvent()); } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java deleted file mode 100644 index a977010c6..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Channel.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.iluwatar.eda.advanced; - - -public interface Channel { - public void dispatch(E message); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java deleted file mode 100644 index f72b79150..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/DynamicRouter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.iluwatar.eda.advanced; - -public interface DynamicRouter { - public void registerChannel(Class contentType, Channel channel); - public void dispatch(E content); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java index def8920c1..468160b45 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java @@ -1,18 +1,23 @@ package com.iluwatar.eda.advanced; +import com.iluwatar.eda.advanced.events.Event; +import com.iluwatar.eda.advanced.framework.Channel; +import com.iluwatar.eda.advanced.framework.DynamicRouter; + import java.util.HashMap; import java.util.Map; public class EventDispatcher implements DynamicRouter { - private Map, Handler> handlers; + + private Map, Channel> handlers; public EventDispatcher() { - handlers = new HashMap, Handler>(); + handlers = new HashMap, Channel>(); } public void registerChannel(Class contentType, - Channel channel) { - handlers.put(contentType, (Handler)channel); + Channel channel) { + handlers.put(contentType, channel); } public void dispatch(Event content) { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java deleted file mode 100644 index 68631b207..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Handler.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.iluwatar.eda.advanced; - -public class Handler implements Channel { - public void dispatch(Event message) { - System.out.println(message.getClass()); - } -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java similarity index 56% rename from event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java rename to event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java index 8ad48c704..64b51ea84 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Event.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java @@ -1,4 +1,6 @@ -package com.iluwatar.eda.advanced; +package com.iluwatar.eda.advanced.events; + +import com.iluwatar.eda.advanced.framework.Message; public class Event implements Message { public Class getType() { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java new file mode 100644 index 000000000..75dc776de --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java @@ -0,0 +1,9 @@ +package com.iluwatar.eda.advanced.events; + +import com.iluwatar.eda.advanced.events.Event; + +/** + * @author cfarrugia + */ +public class UserCreatedEvent extends Event { +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java new file mode 100644 index 000000000..df1c0af43 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java @@ -0,0 +1,6 @@ +package com.iluwatar.eda.advanced.events; + +import com.iluwatar.eda.advanced.events.Event; + +public class UserUpdatedEvent extends Event { +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java new file mode 100644 index 000000000..20a1cceaa --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java @@ -0,0 +1,8 @@ +package com.iluwatar.eda.advanced.framework; + + +import com.iluwatar.eda.advanced.events.Event; + +public interface Channel { + void dispatch(E message); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java new file mode 100644 index 000000000..2ae7291f9 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java @@ -0,0 +1,6 @@ +package com.iluwatar.eda.advanced.framework; + +public interface DynamicRouter { + void registerChannel(Class contentType, Channel channel); + void dispatch(E content); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java similarity index 63% rename from event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java rename to event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java index 00d335191..6243dda97 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/Message.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java @@ -1,4 +1,4 @@ -package com.iluwatar.eda.advanced; +package com.iluwatar.eda.advanced.framework; public interface Message { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java new file mode 100644 index 000000000..caacd5583 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java @@ -0,0 +1,15 @@ +package com.iluwatar.eda.advanced.handler; + +import com.iluwatar.eda.advanced.events.Event; +import com.iluwatar.eda.advanced.events.UserCreatedEvent; +import com.iluwatar.eda.advanced.framework.Channel; + +/** + * @author cfarrugia + */ +public class UserCreatedEventHandler implements Channel { + + public void dispatch(UserCreatedEvent message) { + System.out.println("User Created!"); + } +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java new file mode 100644 index 000000000..dada6fafc --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java @@ -0,0 +1,12 @@ +package com.iluwatar.eda.advanced.handler; + +import com.iluwatar.eda.advanced.events.Event; +import com.iluwatar.eda.advanced.events.UserUpdatedEvent; +import com.iluwatar.eda.advanced.framework.Channel; + +public class UserUpdatedEventHandler implements Channel { + + public void dispatch(UserUpdatedEvent message) { + System.out.println("User Updated!"); + } +} From b4aeca3aa0117e899c87e4b648fc7acc3601aa1f Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 23 Nov 2015 00:04:44 +0100 Subject: [PATCH 003/106] #113 Event Driven Architecture - removed unused imports --- .../iluwatar/eda/advanced/handler/UserCreatedEventHandler.java | 1 - .../iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java | 1 - 2 files changed, 2 deletions(-) diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java index caacd5583..f3f4535d1 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java @@ -1,6 +1,5 @@ package com.iluwatar.eda.advanced.handler; -import com.iluwatar.eda.advanced.events.Event; import com.iluwatar.eda.advanced.events.UserCreatedEvent; import com.iluwatar.eda.advanced.framework.Channel; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java index dada6fafc..8ed5dcf51 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java @@ -1,6 +1,5 @@ package com.iluwatar.eda.advanced.handler; -import com.iluwatar.eda.advanced.events.Event; import com.iluwatar.eda.advanced.events.UserUpdatedEvent; import com.iluwatar.eda.advanced.framework.Channel; From 321e9d4191cdb1a3592ce758fcc0238e31f3af19 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 23 Nov 2015 11:20:20 +0100 Subject: [PATCH 004/106] #113 Event Driven Architecture - added class diagram - added more comments --- .../etc/class_diagram.png | Bin 0 -> 38232 bytes event-driven-architecture/index.md | 6 ++- .../src/main/java/com/iluwatar/eda/App.java | 28 +++++++++++++ .../com/iluwatar/eda/EventDispatcher.java | 39 ++++++++++++++++++ .../java/com/iluwatar/eda/advanced/App.java | 18 -------- .../eda/advanced/EventDispatcher.java | 26 ------------ .../eda/advanced/events/UserCreatedEvent.java | 9 ---- .../eda/advanced/events/UserUpdatedEvent.java | 6 --- .../eda/advanced/framework/Channel.java | 8 ---- .../eda/advanced/framework/DynamicRouter.java | 6 --- .../eda/advanced/framework/Message.java | 6 --- .../eda/{advanced/events => event}/Event.java | 4 +- .../iluwatar/eda/event/UserCreatedEvent.java | 7 ++++ .../iluwatar/eda/event/UserUpdatedEvent.java | 4 ++ .../com/iluwatar/eda/framework/Channel.java | 9 ++++ .../iluwatar/eda/framework/DynamicRouter.java | 11 +++++ .../com/iluwatar/eda/framework/Message.java | 9 ++++ .../handler/UserCreatedEventHandler.java | 8 ++-- .../handler/UserUpdatedEventHandler.java | 9 ++-- .../java/com/iluwatar/eda/simple/App.java | 38 ----------------- .../java/com/iluwatar/eda/simple/Event.java | 15 ------- .../com/iluwatar/eda/simple/EventHandler.java | 15 ------- 22 files changed, 123 insertions(+), 158 deletions(-) create mode 100644 event-driven-architecture/etc/class_diagram.png create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/App.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java rename event-driven-architecture/src/main/java/com/iluwatar/eda/{advanced/events => event}/Event.java (56%) create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java rename event-driven-architecture/src/main/java/com/iluwatar/eda/{advanced => }/handler/UserCreatedEventHandler.java (52%) rename event-driven-architecture/src/main/java/com/iluwatar/eda/{advanced => }/handler/UserUpdatedEventHandler.java (50%) delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java diff --git a/event-driven-architecture/etc/class_diagram.png b/event-driven-architecture/etc/class_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..69560e1f4b80d0d95dc5387189cc753e31d66f65 GIT binary patch literal 38232 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 + * The example below we uses an {@link EventDispatcher} to link/register {@link Event} objects to + * their respective handlers Once an {@link Event} is dispatched, + * it's respective handler is invoked and the {@link Event} is handled accordingly + */ +public class App { + + public static void main(String[] args) { + EventDispatcher dispatcher = new EventDispatcher(); + dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); + dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); + dispatcher.dispatch(new UserCreatedEvent()); + dispatcher.dispatch(new UserUpdatedEvent()); + } + +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java new file mode 100644 index 000000000..f947773d0 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java @@ -0,0 +1,39 @@ +package com.iluwatar.eda; + +import com.iluwatar.eda.event.Event; +import com.iluwatar.eda.framework.Channel; +import com.iluwatar.eda.framework.DynamicRouter; + +import java.util.HashMap; +import java.util.Map; + +/** + * The {@link Event Dispatcher} handles routing of {@link Event} messages to associated channels. + * A {@link HashMap} is used to store the association between events and their respective handlers. + */ +public class EventDispatcher implements DynamicRouter { + + private Map, Channel> handlers; + + public EventDispatcher() { + handlers = new HashMap, Channel>(); + } + + /** + * Links an {@link Event} to a specific {@link Channel} + * @param contentType The {@link Event} to be registered + * @param channel The {@link Channel} that will be handling the {@link Event} + */ + public void registerChannel(Class contentType, + Channel channel) { + handlers.put(contentType, channel); + } + + /** + * Dispathes an {@link Event} depending on it's type. + * @param content The {@link Event} to be dispatched + */ + public void dispatch(Event content) { + handlers.get(content.getClass()).dispatch(content); + } +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java deleted file mode 100644 index e7b8c01bc..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/App.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.iluwatar.eda.advanced; - -import com.iluwatar.eda.advanced.events.Event; -import com.iluwatar.eda.advanced.events.UserCreatedEvent; -import com.iluwatar.eda.advanced.events.UserUpdatedEvent; -import com.iluwatar.eda.advanced.handler.UserCreatedEventHandler; -import com.iluwatar.eda.advanced.handler.UserUpdatedEventHandler; - -public class App { - - public static void main(String[] args) { - EventDispatcher dispatcher = new EventDispatcher(); - dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); - dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); - dispatcher.dispatch(new UserCreatedEvent()); - dispatcher.dispatch(new UserUpdatedEvent()); - } -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java deleted file mode 100644 index 468160b45..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/EventDispatcher.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.iluwatar.eda.advanced; - -import com.iluwatar.eda.advanced.events.Event; -import com.iluwatar.eda.advanced.framework.Channel; -import com.iluwatar.eda.advanced.framework.DynamicRouter; - -import java.util.HashMap; -import java.util.Map; - -public class EventDispatcher implements DynamicRouter { - - private Map, Channel> handlers; - - public EventDispatcher() { - handlers = new HashMap, Channel>(); - } - - public void registerChannel(Class contentType, - Channel channel) { - handlers.put(contentType, channel); - } - - public void dispatch(Event content) { - handlers.get(content.getClass()).dispatch(content); - } -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java deleted file mode 100644 index 75dc776de..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserCreatedEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.iluwatar.eda.advanced.events; - -import com.iluwatar.eda.advanced.events.Event; - -/** - * @author cfarrugia - */ -public class UserCreatedEvent extends Event { -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java deleted file mode 100644 index df1c0af43..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/UserUpdatedEvent.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.iluwatar.eda.advanced.events; - -import com.iluwatar.eda.advanced.events.Event; - -public class UserUpdatedEvent extends Event { -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java deleted file mode 100644 index 20a1cceaa..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Channel.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.iluwatar.eda.advanced.framework; - - -import com.iluwatar.eda.advanced.events.Event; - -public interface Channel { - void dispatch(E message); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java deleted file mode 100644 index 2ae7291f9..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/DynamicRouter.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.iluwatar.eda.advanced.framework; - -public interface DynamicRouter { - void registerChannel(Class contentType, Channel channel); - void dispatch(E content); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java deleted file mode 100644 index 6243dda97..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/framework/Message.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.iluwatar.eda.advanced.framework; - - -public interface Message { - public Class getType(); -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java similarity index 56% rename from event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java rename to event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java index 64b51ea84..5f3db28e8 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/events/Event.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java @@ -1,6 +1,6 @@ -package com.iluwatar.eda.advanced.events; +package com.iluwatar.eda.event; -import com.iluwatar.eda.advanced.framework.Message; +import com.iluwatar.eda.framework.Message; public class Event implements Message { public Class getType() { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java new file mode 100644 index 000000000..14d83a783 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -0,0 +1,7 @@ +package com.iluwatar.eda.event; + +/** + * @author cfarrugia + */ +public class UserCreatedEvent extends Event { +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java new file mode 100644 index 000000000..e0e3c3cd6 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -0,0 +1,4 @@ +package com.iluwatar.eda.event; + +public class UserUpdatedEvent extends Event { +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java new file mode 100644 index 000000000..a8dd97044 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java @@ -0,0 +1,9 @@ +package com.iluwatar.eda.framework; + +/** + * Channels are delivery points for messages. + * Every {@link Channel} is responsible for a single type of message + */ +public interface Channel { + void dispatch(E message); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java new file mode 100644 index 000000000..751318ada --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java @@ -0,0 +1,11 @@ +package com.iluwatar.eda.framework; + +/** + * A {@link DynamicRouter} is responsible for selecting the proper path of a {@link Message} + * Messages can be associated to Channels through the registerChannel method and dispatched by calling + * the dispatch method. + */ +public interface DynamicRouter { + void registerChannel(Class contentType, Channel channel); + void dispatch(E content); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java new file mode 100644 index 000000000..61880e9cd --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java @@ -0,0 +1,9 @@ +package com.iluwatar.eda.framework; + +/** + * A {@link Message} is an object with a specific type that is associated to a + * specific {@link Channel} + */ +public interface Message { + Class getType(); +} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java similarity index 52% rename from event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java rename to event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java index f3f4535d1..b2e831bf8 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserCreatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java @@ -1,10 +1,10 @@ -package com.iluwatar.eda.advanced.handler; +package com.iluwatar.eda.handler; -import com.iluwatar.eda.advanced.events.UserCreatedEvent; -import com.iluwatar.eda.advanced.framework.Channel; +import com.iluwatar.eda.event.UserCreatedEvent; +import com.iluwatar.eda.framework.Channel; /** - * @author cfarrugia + * Handles the {@link UserCreatedEvent} message */ public class UserCreatedEventHandler implements Channel { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java similarity index 50% rename from event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java rename to event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java index 8ed5dcf51..c7762d247 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/advanced/handler/UserUpdatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java @@ -1,8 +1,11 @@ -package com.iluwatar.eda.advanced.handler; +package com.iluwatar.eda.handler; -import com.iluwatar.eda.advanced.events.UserUpdatedEvent; -import com.iluwatar.eda.advanced.framework.Channel; +import com.iluwatar.eda.event.UserUpdatedEvent; +import com.iluwatar.eda.framework.Channel; +/** + * Handles the {@link UserUpdatedEvent} message + */ public class UserUpdatedEventHandler implements Channel { public void dispatch(UserUpdatedEvent message) { diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java deleted file mode 100644 index 1399811bb..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/App.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.iluwatar.eda.simple; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * Event-driven architecture (EDA) is a software architecture pattern promoting - * the production, detection, consumption of, and reaction to events. - *

- * This main class publishes events to queue. Each event on the queue is consumed - * and handled depending on the type defined in the {@link Event} - */ -public class App { - - public static void main(String args[]) { - - //create a list of events having different types - //add these events to a simple queue - Queue events = new LinkedList(); - events.add(new Event('A', "Hello")); - events.add(new Event('B', "event-driven")); - events.add(new Event('A', "world!")); - - Event e; - - //the event loop will go through the list of events - //and handle each one depending on it's type - while (!events.isEmpty()) { - e = events.remove(); - - //handle events depending on their type - if (e.type == 'A') - EventHandler.handleEventA(e); - if (e.type == 'B') - EventHandler.handleEventB(e); - } - } -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java deleted file mode 100644 index 1ba04c303..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/Event.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.iluwatar.eda.simple; - -/** - * The Event class defines the type of event and data related to the event. - */ -public class Event { - - public char type; - public String data; - - public Event(char type, String data){ - this.type = type; - this.data = data; - } -} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java deleted file mode 100644 index d911c6c8e..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/simple/EventHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.iluwatar.eda.simple; - -/** - * The {@link EventHandler} class handles performs actions on {@link Event} objects - */ -public class EventHandler { - - public static void handleEventA(Event e){ - System.out.println(e.data); - } - - public static void handleEventB(Event e){ - System.out.println(e.data.toUpperCase()); - } -} From fc70a706c680ff1e58cf930846dbe2f3d15b8240 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 10:57:00 +0100 Subject: [PATCH 005/106] #113 Event Driven Architecture Adds module to the root pom.xml Fixes indentation --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index bcdf9affe..e0e6a0cc6 100644 --- a/pom.xml +++ b/pom.xml @@ -76,16 +76,17 @@ front-controller repository async-method-invocation - monostate + monostate step-builder - business-delegate - half-sync-half-async + business-delegate + half-sync-half-async layers message-channel fluentinterface reactor caching publish-subscribe + event-driven-architecture From b8b94b697aef8601f4d2564b8be7ee2a443f7688 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 13:12:16 +0100 Subject: [PATCH 006/106] #113 Event Driven Architecture Adds more Javadoc --- event-driven-architecture/pom.xml | 24 ++++++++++ .../src/main/java/com/iluwatar/eda/App.java | 27 ++++++----- .../com/iluwatar/eda/EventDispatcher.java | 46 ++++++++++--------- .../java/com/iluwatar/eda/event/Event.java | 23 ++++++++-- .../iluwatar/eda/event/UserCreatedEvent.java | 3 +- .../iluwatar/eda/event/UserUpdatedEvent.java | 4 ++ .../com/iluwatar/eda/framework/Channel.java | 8 ++-- .../iluwatar/eda/framework/DynamicRouter.java | 10 ++-- .../com/iluwatar/eda/framework/Message.java | 6 +-- .../eda/handler/UserCreatedEventHandler.java | 9 ++-- .../eda/handler/UserUpdatedEventHandler.java | 9 ++-- pom.xml | 4 +- 12 files changed, 112 insertions(+), 61 deletions(-) diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index fdea3855f..0c72f2157 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -19,4 +19,28 @@ test + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.15 + + + validate + + check + + validate + + checkstyle.xml + UTF-8 + true + true + + + + + + \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java index e8b8d2d09..ab4b2e489 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java @@ -7,22 +7,21 @@ import com.iluwatar.eda.handler.UserCreatedEventHandler; import com.iluwatar.eda.handler.UserUpdatedEventHandler; /** - * An event-driven architecture (EDA) is a framework that orchestrates behavior around the production, - * detection and consumption of events as well as the responses they evoke. - * An event is any identifiable occurrence that has significance for system hardware or software. - *

- * The example below we uses an {@link EventDispatcher} to link/register {@link Event} objects to - * their respective handlers Once an {@link Event} is dispatched, - * it's respective handler is invoked and the {@link Event} is handled accordingly + * An event-driven architecture (EDA) is a framework that orchestrates behavior around the + * production, detection and consumption of events as well as the responses they evoke. An event is + * any identifiable occurrence that has significance for system hardware or software.

The + * example below we uses an {@link EventDispatcher} to link/register {@link Event} objects to their + * respective handlers Once an {@link Event} is dispatched, it's respective handler is invoked and + * the {@link Event} is handled accordingly */ public class App { - public static void main(String[] args) { - EventDispatcher dispatcher = new EventDispatcher(); - dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); - dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); - dispatcher.dispatch(new UserCreatedEvent()); - dispatcher.dispatch(new UserUpdatedEvent()); - } + public static void main(String[] args) { + EventDispatcher dispatcher = new EventDispatcher(); + dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); + dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); + dispatcher.dispatch(new UserCreatedEvent()); + dispatcher.dispatch(new UserUpdatedEvent()); + } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java index f947773d0..3b44a414a 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java @@ -8,32 +8,36 @@ import java.util.HashMap; import java.util.Map; /** - * The {@link Event Dispatcher} handles routing of {@link Event} messages to associated channels. + * The {@link Event Dispatcher} handles routing of {@link Event} messages + * to associated channels. * A {@link HashMap} is used to store the association between events and their respective handlers. + * */ public class EventDispatcher implements DynamicRouter { - private Map, Channel> handlers; + private Map, Channel> handlers; - public EventDispatcher() { - handlers = new HashMap, Channel>(); - } + public EventDispatcher() { + handlers = new HashMap<>(); + } - /** - * Links an {@link Event} to a specific {@link Channel} - * @param contentType The {@link Event} to be registered - * @param channel The {@link Channel} that will be handling the {@link Event} - */ - public void registerChannel(Class contentType, - Channel channel) { - handlers.put(contentType, channel); - } + /** + * Links an {@link Event} to a specific {@link Channel} + * + * @param contentType The {@link Event} to be registered + * @param channel The {@link Channel} that will be handling the {@link Event} + */ + public void registerChannel(Class contentType, + Channel channel) { + handlers.put(contentType, channel); + } - /** - * Dispathes an {@link Event} depending on it's type. - * @param content The {@link Event} to be dispatched - */ - public void dispatch(Event content) { - handlers.get(content.getClass()).dispatch(content); - } + /** + * Dispatches an {@link Event} depending on it's type. + * + * @param content The {@link Event} to be dispatched + */ + public void dispatch(Event content) { + handlers.get(content.getClass()).dispatch(content); + } } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java index 5f3db28e8..9a2518ebf 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java @@ -2,8 +2,25 @@ package com.iluwatar.eda.event; import com.iluwatar.eda.framework.Message; +/** + * The {@link Event} class serves as a base class for defining custom events happening with your + * system. In this example we have two types of events defined. + *

    + *
  • {@link UserCreatedEvent} - used when a user is created
  • + *
  • {@link UserUpdatedEvent} - used when a user is updated
  • + *
+ * Events can be distinguished using the {@link #getType() getType} method. + */ public class Event implements Message { - public Class getType() { - return getClass(); - } + + /** + * Returns the event type as a {@link Class} object + * In this example, this method is used by the {@link com.iluwatar.eda.EventDispatcher} to + * dispatch events depending on their type. + * + * @return the Event type as a {@link Class}. + */ + public Class getType() { + return getClass(); + } } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index 14d83a783..1a61dfa59 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -1,7 +1,8 @@ package com.iluwatar.eda.event; /** - * @author cfarrugia + * The {@link UserCreatedEvent} class should should be dispatched whenever a user has been created. + * This class can be extended to contain details about the user has been created. */ public class UserCreatedEvent extends Event { } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java index e0e3c3cd6..3b401ecd1 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -1,4 +1,8 @@ package com.iluwatar.eda.event; +/** + * The {@link UserUpdatedEvent} class should should be dispatched whenever a user has been updated. + * This class can be extended to contain details about the user has been updated. + */ public class UserUpdatedEvent extends Event { } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java index a8dd97044..32eca09d4 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java @@ -1,9 +1,11 @@ package com.iluwatar.eda.framework; +import com.iluwatar.eda.event.Event; + /** - * Channels are delivery points for messages. - * Every {@link Channel} is responsible for a single type of message + * Channels are delivery points for messages. Every {@link Channel} is responsible for a single type + * of message */ public interface Channel { - void dispatch(E message); + void dispatch(E message); } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java index 751318ada..23fd6044f 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java @@ -2,10 +2,12 @@ package com.iluwatar.eda.framework; /** * A {@link DynamicRouter} is responsible for selecting the proper path of a {@link Message} - * Messages can be associated to Channels through the registerChannel method and dispatched by calling - * the dispatch method. + * Messages can be associated to Channels through the registerChannel method and dispatched by + * calling the dispatch method. */ public interface DynamicRouter { - void registerChannel(Class contentType, Channel channel); - void dispatch(E content); + + void registerChannel(Class contentType, Channel channel); + + void dispatch(E content); } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java index 61880e9cd..2f8acb343 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java @@ -1,9 +1,9 @@ package com.iluwatar.eda.framework; /** - * A {@link Message} is an object with a specific type that is associated to a - * specific {@link Channel} + * A {@link Message} is an object with a specific type that is associated + * to a specific {@link Channel}. */ public interface Message { - Class getType(); + Class getType(); } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java index b2e831bf8..e406f7c51 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java @@ -4,11 +4,10 @@ import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.framework.Channel; /** - * Handles the {@link UserCreatedEvent} message + * Handles the {@link UserCreatedEvent} message. */ public class UserCreatedEventHandler implements Channel { - - public void dispatch(UserCreatedEvent message) { - System.out.println("User Created!"); - } + public void dispatch(UserCreatedEvent message) { + System.out.println("User Created!"); + } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java index c7762d247..d59954806 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java @@ -4,11 +4,10 @@ import com.iluwatar.eda.event.UserUpdatedEvent; import com.iluwatar.eda.framework.Channel; /** - * Handles the {@link UserUpdatedEvent} message + * Handles the {@link UserUpdatedEvent} message. */ public class UserUpdatedEventHandler implements Channel { - - public void dispatch(UserUpdatedEvent message) { - System.out.println("User Updated!"); - } + public void dispatch(UserUpdatedEvent message) { + System.out.println("User Updated!"); + } } diff --git a/pom.xml b/pom.xml index e0e6a0cc6..9e4c39bf9 100644 --- a/pom.xml +++ b/pom.xml @@ -244,8 +244,8 @@ checkstyle.xml UTF-8 - false - false + true + true From e1c0731f7e2c58fba76c3c6ec393890b578e4370 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 15:03:22 +0100 Subject: [PATCH 007/106] #113 Event Driven Architecture Adds more Javadoc and fixes checkstyle issues. --- event-driven-architecture/pom.xml | 25 +------------------ .../src/main/java/com/iluwatar/eda/App.java | 24 ++++++++++++++---- .../com/iluwatar/eda/EventDispatcher.java | 7 +++--- .../iluwatar/eda/event/UserCreatedEvent.java | 16 +++++++++++- .../iluwatar/eda/event/UserUpdatedEvent.java | 15 ++++++++++- .../com/iluwatar/eda/framework/Channel.java | 2 +- .../eda/handler/UserCreatedEventHandler.java | 10 ++++++-- .../eda/handler/UserUpdatedEventHandler.java | 10 ++++++-- .../java/com/iluwatar/eda/model/User.java | 21 ++++++++++++++++ 9 files changed, 90 insertions(+), 40 deletions(-) create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index 0c72f2157..2c011759b 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -19,28 +19,5 @@ test - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.15 - - - validate - - check - - validate - - checkstyle.xml - UTF-8 - true - true - - - - - - + \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java index ab4b2e489..5ef58d20b 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java @@ -5,23 +5,37 @@ import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent; import com.iluwatar.eda.handler.UserCreatedEventHandler; import com.iluwatar.eda.handler.UserUpdatedEventHandler; +import com.iluwatar.eda.model.User; /** * An event-driven architecture (EDA) is a framework that orchestrates behavior around the * production, detection and consumption of events as well as the responses they evoke. An event is * any identifiable occurrence that has significance for system hardware or software.

The - * example below we uses an {@link EventDispatcher} to link/register {@link Event} objects to their - * respective handlers Once an {@link Event} is dispatched, it's respective handler is invoked and - * the {@link Event} is handled accordingly + * example below uses an {@link EventDispatcher} to link/register {@link Event} objects to their + * respective handlers once an {@link Event} is dispatched, it's respective handler is invoked and + * the {@link Event} is handled accordingly. + * */ public class App { + /** + * Once the {@link EventDispatcher} is initialised, channels related to specific events have to be + * made known to the dispatcher by registering them. In this case the {@link UserCreatedEvent} is + * bound to the UserCreatedEventHandler, whilst the {@link UserUpdatedEvent} is bound to the + * {@link UserUpdatedEventHandler}. The dispatcher can now be called to dispatch specific events. + * When a user is saved, the {@link UserCreatedEvent} can be dispatched. + * On the other hand, when a user is updated, {@link UserUpdatedEvent} can be dispatched. + * + */ public static void main(String[] args) { + EventDispatcher dispatcher = new EventDispatcher(); dispatcher.registerChannel(UserCreatedEvent.class, new UserCreatedEventHandler()); dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); - dispatcher.dispatch(new UserCreatedEvent()); - dispatcher.dispatch(new UserUpdatedEvent()); + + User user = new User("iluwatar"); + dispatcher.dispatch(new UserCreatedEvent(user)); + dispatcher.dispatch(new UserUpdatedEvent(user)); } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java index 3b44a414a..e52f9db46 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java @@ -8,21 +8,20 @@ import java.util.HashMap; import java.util.Map; /** - * The {@link Event Dispatcher} handles routing of {@link Event} messages - * to associated channels. + * Handles the routing of {@link Event} messages to associated channels. * A {@link HashMap} is used to store the association between events and their respective handlers. * */ public class EventDispatcher implements DynamicRouter { - private Map, Channel> handlers; + private Map, Channel> handlers; public EventDispatcher() { handlers = new HashMap<>(); } /** - * Links an {@link Event} to a specific {@link Channel} + * Links an {@link Event} to a specific {@link Channel}. * * @param contentType The {@link Event} to be registered * @param channel The {@link Channel} that will be handling the {@link Event} diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index 1a61dfa59..3d6187b7e 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -1,8 +1,22 @@ package com.iluwatar.eda.event; +import com.iluwatar.eda.model.User; + /** * The {@link UserCreatedEvent} class should should be dispatched whenever a user has been created. - * This class can be extended to contain details about the user has been created. + * This class can be extended to contain details about the user has been created. In this example, + * the entire {@link User} object is passed on as data with the event. */ public class UserCreatedEvent extends Event { + + private User user; + + public UserCreatedEvent(User user) { + this.user = user; + } + + + public User getUser() { + return user; + } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java index 3b401ecd1..f3bce8124 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -1,8 +1,21 @@ package com.iluwatar.eda.event; +import com.iluwatar.eda.model.User; + /** * The {@link UserUpdatedEvent} class should should be dispatched whenever a user has been updated. - * This class can be extended to contain details about the user has been updated. + * This class can be extended to contain details about the user has been updated. In this example, + * the entire {@link User} object is passed on as data with the event. */ public class UserUpdatedEvent extends Event { + + private User user; + + public UserUpdatedEvent(User user) { + this.user = user; + } + + public User getUser() { + return user; + } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java index 32eca09d4..1684a9641 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java @@ -7,5 +7,5 @@ import com.iluwatar.eda.event.Event; * of message */ public interface Channel { - void dispatch(E message); + void dispatch(Event message); } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java index e406f7c51..49d209eb0 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java @@ -1,13 +1,19 @@ package com.iluwatar.eda.handler; +import com.iluwatar.eda.event.Event; import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.framework.Channel; +import com.iluwatar.eda.model.User; /** * Handles the {@link UserCreatedEvent} message. */ public class UserCreatedEventHandler implements Channel { - public void dispatch(UserCreatedEvent message) { - System.out.println("User Created!"); + + @Override + public void dispatch(Event message) { + + UserCreatedEvent userCreatedEvent = (UserCreatedEvent) message; + System.out.printf("User with %s has been Created!", userCreatedEvent.getUser().getUsername()); } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java index d59954806..fd3a6d3ba 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java @@ -1,5 +1,7 @@ package com.iluwatar.eda.handler; +import com.iluwatar.eda.event.Event; +import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent; import com.iluwatar.eda.framework.Channel; @@ -7,7 +9,11 @@ import com.iluwatar.eda.framework.Channel; * Handles the {@link UserUpdatedEvent} message. */ public class UserUpdatedEventHandler implements Channel { - public void dispatch(UserUpdatedEvent message) { - System.out.println("User Updated!"); + + @Override + public void dispatch(Event message) { + + UserUpdatedEvent userUpdatedEvent = (UserUpdatedEvent) message; + System.out.printf("User with %s has been Updated!", userUpdatedEvent.getUser().getUsername()); } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java new file mode 100644 index 000000000..02a7a4641 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java @@ -0,0 +1,21 @@ +package com.iluwatar.eda.model; + +import com.iluwatar.eda.event.UserCreatedEvent; +import com.iluwatar.eda.event.UserUpdatedEvent; + +/** + * This {@link User} class is a basic pojo used to demonstrate user data sent along with + * the {@link UserCreatedEvent} and {@link UserUpdatedEvent} events. + */ +public class User { + + private String username; + + public User(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } +} From 3ad36020aac253a0b1cbf857db7825cd729ee108 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 17:25:15 +0100 Subject: [PATCH 008/106] #113 Event Driven Architecture Adds unit test to assert and verify pattern behaviour --- event-driven-architecture/pom.xml | 7 ++- .../com/iluwatar/eda/EventDispatcher.java | 8 ++++ .../iluwatar/eda/event/UserCreatedEvent.java | 1 - .../src/test/java/EventDrivenTest.java | 47 +++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 event-driven-architecture/src/test/java/EventDrivenTest.java diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index 2c011759b..77504657f 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -18,6 +18,11 @@ junit test - + + org.mockito + mockito-core + test + + \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java index e52f9db46..89f8de71b 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java @@ -39,4 +39,12 @@ public class EventDispatcher implements DynamicRouter { public void dispatch(Event content) { handlers.get(content.getClass()).dispatch(content); } + + /** + * Returns a map of registered event handlers. + * @return {@Map} of registered event handlers. + */ + public Map, Channel> getHandlers() { + return handlers; + } } \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index 3d6187b7e..da2e31c8a 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -15,7 +15,6 @@ public class UserCreatedEvent extends Event { this.user = user; } - public User getUser() { return user; } diff --git a/event-driven-architecture/src/test/java/EventDrivenTest.java b/event-driven-architecture/src/test/java/EventDrivenTest.java new file mode 100644 index 000000000..70579d557 --- /dev/null +++ b/event-driven-architecture/src/test/java/EventDrivenTest.java @@ -0,0 +1,47 @@ +import com.iluwatar.eda.EventDispatcher; +import com.iluwatar.eda.event.UserCreatedEvent; +import com.iluwatar.eda.event.UserUpdatedEvent; +import com.iluwatar.eda.handler.UserCreatedEventHandler; +import com.iluwatar.eda.handler.UserUpdatedEventHandler; +import com.iluwatar.eda.model.User; + +import org.junit.Test; + + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import static org.junit.Assert.assertEquals; + +public class EventDrivenTest { + + @Test + public void testEventDriverPattern(){ + + EventDispatcher dispatcher = spy(new EventDispatcher()); + UserCreatedEventHandler userCreatedEventHandler = new UserCreatedEventHandler(); + UserUpdatedEventHandler userUpdatedEventHandler = new UserUpdatedEventHandler(); + dispatcher.registerChannel(UserCreatedEvent.class, userCreatedEventHandler); + dispatcher.registerChannel(UserUpdatedEvent.class, userUpdatedEventHandler); + + assertEquals("Two handlers must be registered", 2, dispatcher.getHandlers().size()); + assertEquals("UserCreatedEvent must return the UserCreatedEventHandler", + userCreatedEventHandler, + (UserCreatedEventHandler)dispatcher.getHandlers().get(UserCreatedEvent.class)); + assertEquals("UserUpdatedEvent must be registered to the UserUpdatedEventHandler", + userUpdatedEventHandler, + (UserUpdatedEventHandler)dispatcher.getHandlers().get(UserUpdatedEvent.class)); + + User user = new User("iluwatar"); + + UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); + UserUpdatedEvent userUpdatedEvent = new UserUpdatedEvent(user); + dispatcher.dispatch(userCreatedEvent); + dispatcher.dispatch(userUpdatedEvent); + + //verify that the events have been dispatched + verify(dispatcher).dispatch(userCreatedEvent); + verify(dispatcher).dispatch(userUpdatedEvent); + + } +} From d9a1d1cef9184bda742e1164d7c1887735b47e82 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 17:58:32 +0100 Subject: [PATCH 009/106] #113 Event Driven Architecture Adds unit test to assert and verify pattern event get type behaviour. Also added unit test comments. --- .../src/test/java/EventDrivenTest.java | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/event-driven-architecture/src/test/java/EventDrivenTest.java b/event-driven-architecture/src/test/java/EventDrivenTest.java index 70579d557..addc5fafa 100644 --- a/event-driven-architecture/src/test/java/EventDrivenTest.java +++ b/event-driven-architecture/src/test/java/EventDrivenTest.java @@ -1,4 +1,5 @@ import com.iluwatar.eda.EventDispatcher; +import com.iluwatar.eda.event.Event; import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent; import com.iluwatar.eda.handler.UserCreatedEventHandler; @@ -6,20 +7,25 @@ import com.iluwatar.eda.handler.UserUpdatedEventHandler; import com.iluwatar.eda.model.User; import org.junit.Test; - - import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; - import static org.junit.Assert.assertEquals; + +/** + * Event Driven Pattern unit tests to assert and verify correct pattern behaviour + */ public class EventDrivenTest { + /** + * This unit test should register events and event handlers correctly with the event dispatcher + * and events should be dispatched accordingly. + */ @Test - public void testEventDriverPattern(){ + public void testEventDriverPattern() { EventDispatcher dispatcher = spy(new EventDispatcher()); - UserCreatedEventHandler userCreatedEventHandler = new UserCreatedEventHandler(); + UserCreatedEventHandler userCreatedEventHandler = new UserCreatedEventHandler(); UserUpdatedEventHandler userUpdatedEventHandler = new UserUpdatedEventHandler(); dispatcher.registerChannel(UserCreatedEvent.class, userCreatedEventHandler); dispatcher.registerChannel(UserUpdatedEvent.class, userUpdatedEventHandler); @@ -27,10 +33,10 @@ public class EventDrivenTest { assertEquals("Two handlers must be registered", 2, dispatcher.getHandlers().size()); assertEquals("UserCreatedEvent must return the UserCreatedEventHandler", userCreatedEventHandler, - (UserCreatedEventHandler)dispatcher.getHandlers().get(UserCreatedEvent.class)); + (UserCreatedEventHandler) dispatcher.getHandlers().get(UserCreatedEvent.class)); assertEquals("UserUpdatedEvent must be registered to the UserUpdatedEventHandler", userUpdatedEventHandler, - (UserUpdatedEventHandler)dispatcher.getHandlers().get(UserUpdatedEvent.class)); + (UserUpdatedEventHandler) dispatcher.getHandlers().get(UserUpdatedEvent.class)); User user = new User("iluwatar"); @@ -42,6 +48,16 @@ public class EventDrivenTest { //verify that the events have been dispatched verify(dispatcher).dispatch(userCreatedEvent); verify(dispatcher).dispatch(userUpdatedEvent); + } + /** + * This unit test should correctly return the {@link Event} class type when calling the + * {@link Event#getType() getType} method. + */ + @Test + public void testGetEventType() { + User user = new User("iluwatar"); + UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); + assertEquals(UserCreatedEvent.class, userCreatedEvent.getType()); } } From 9e857d7dd6e6f0653953c4da787a72c2cfd0c0be Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Sat, 28 Nov 2015 19:05:23 +0100 Subject: [PATCH 010/106] #113 Event Driven Architecture Fixed javadoc --- .../src/main/java/com/iluwatar/eda/EventDispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java index 89f8de71b..f68fdb71b 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java @@ -42,7 +42,7 @@ public class EventDispatcher implements DynamicRouter { /** * Returns a map of registered event handlers. - * @return {@Map} of registered event handlers. + * @return {@link Map} of registered event handlers. */ public Map, Channel> getHandlers() { return handlers; From cfb0fafc7d5f98ec94cd41ffaaf28af80489dc6c Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Tue, 1 Dec 2015 23:30:01 +0100 Subject: [PATCH 011/106] #113 Event Driven Architecture Adds various changes including : - Fixes to Javadoc - Test refactoring and improvements - Refactored EventDispatcher to be immutable - Removed DynamicRouter interface since it not needed - Renamed Channel to a more appropriate name - Handler --- event-driven-architecture/index.md | 1 - .../src/main/java/com/iluwatar/eda/App.java | 7 ++- .../com/iluwatar/eda/EventDispatcher.java | 50 --------------- .../java/com/iluwatar/eda/event/Event.java | 5 +- .../iluwatar/eda/event/UserCreatedEvent.java | 2 +- .../iluwatar/eda/event/UserUpdatedEvent.java | 2 +- .../com/iluwatar/eda/framework/Channel.java | 11 ---- .../iluwatar/eda/framework/DynamicRouter.java | 13 ---- .../eda/framework/EventDispatcher.java | 42 +++++++++++++ .../com/iluwatar/eda/framework/Handler.java | 18 ++++++ .../com/iluwatar/eda/framework/Message.java | 8 ++- .../eda/handler/UserCreatedEventHandler.java | 7 +-- .../eda/handler/UserUpdatedEventHandler.java | 7 +-- .../src/test/java/EventDrivenTest.java | 63 ------------------- .../eda/event/UserCreatedEventTest.java | 24 +++++++ .../eda/framework/EventDispatcherTest.java | 50 +++++++++++++++ 16 files changed, 156 insertions(+), 154 deletions(-) delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java delete mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java create mode 100644 event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Handler.java delete mode 100644 event-driven-architecture/src/test/java/EventDrivenTest.java create mode 100644 event-driven-architecture/src/test/java/com/iluwatar/eda/event/UserCreatedEventTest.java create mode 100644 event-driven-architecture/src/test/java/com/iluwatar/eda/framework/EventDispatcherTest.java diff --git a/event-driven-architecture/index.md b/event-driven-architecture/index.md index fb438c3e9..0a4be0bb6 100644 --- a/event-driven-architecture/index.md +++ b/event-driven-architecture/index.md @@ -30,4 +30,3 @@ permalink: /patterns/event-driven-architecture * [Fundamental Components of an Event-Driven Architecture](http://giocc.com/fundamental-components-of-an-event-driven-architecture.html) * [Real World Applications/Event Driven Applications](https://wiki.haskell.org/Real_World_Applications/Event_Driven_Applications) * [Event-driven architecture definition](http://searchsoa.techtarget.com/definition/event-driven-architecture) -* \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java index 5ef58d20b..a1e4c6652 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/App.java @@ -3,6 +3,7 @@ package com.iluwatar.eda; import com.iluwatar.eda.event.Event; import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent; +import com.iluwatar.eda.framework.EventDispatcher; import com.iluwatar.eda.handler.UserCreatedEventHandler; import com.iluwatar.eda.handler.UserUpdatedEventHandler; import com.iluwatar.eda.model.User; @@ -19,7 +20,7 @@ import com.iluwatar.eda.model.User; public class App { /** - * Once the {@link EventDispatcher} is initialised, channels related to specific events have to be + * Once the {@link EventDispatcher} is initialised, handlers related to specific events have to be * made known to the dispatcher by registering them. In this case the {@link UserCreatedEvent} is * bound to the UserCreatedEventHandler, whilst the {@link UserUpdatedEvent} is bound to the * {@link UserUpdatedEventHandler}. The dispatcher can now be called to dispatch specific events. @@ -34,8 +35,8 @@ public class App { dispatcher.registerChannel(UserUpdatedEvent.class, new UserUpdatedEventHandler()); User user = new User("iluwatar"); - dispatcher.dispatch(new UserCreatedEvent(user)); - dispatcher.dispatch(new UserUpdatedEvent(user)); + dispatcher.onEvent(new UserCreatedEvent(user)); + dispatcher.onEvent(new UserUpdatedEvent(user)); } } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java deleted file mode 100644 index f68fdb71b..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/EventDispatcher.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.iluwatar.eda; - -import com.iluwatar.eda.event.Event; -import com.iluwatar.eda.framework.Channel; -import com.iluwatar.eda.framework.DynamicRouter; - -import java.util.HashMap; -import java.util.Map; - -/** - * Handles the routing of {@link Event} messages to associated channels. - * A {@link HashMap} is used to store the association between events and their respective handlers. - * - */ -public class EventDispatcher implements DynamicRouter { - - private Map, Channel> handlers; - - public EventDispatcher() { - handlers = new HashMap<>(); - } - - /** - * Links an {@link Event} to a specific {@link Channel}. - * - * @param contentType The {@link Event} to be registered - * @param channel The {@link Channel} that will be handling the {@link Event} - */ - public void registerChannel(Class contentType, - Channel channel) { - handlers.put(contentType, channel); - } - - /** - * Dispatches an {@link Event} depending on it's type. - * - * @param content The {@link Event} to be dispatched - */ - public void dispatch(Event content) { - handlers.get(content.getClass()).dispatch(content); - } - - /** - * Returns a map of registered event handlers. - * @return {@link Map} of registered event handlers. - */ - public Map, Channel> getHandlers() { - return handlers; - } -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java index 9a2518ebf..9ef3dd7db 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java @@ -1,5 +1,6 @@ package com.iluwatar.eda.event; +import com.iluwatar.eda.framework.EventDispatcher; import com.iluwatar.eda.framework.Message; /** @@ -15,8 +16,8 @@ public class Event implements Message { /** * Returns the event type as a {@link Class} object - * In this example, this method is used by the {@link com.iluwatar.eda.EventDispatcher} to - * dispatch events depending on their type. + * In this example, this method is used by the {@link EventDispatcher} to + * onEvent events depending on their type. * * @return the Event type as a {@link Class}. */ diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index da2e31c8a..f7beaf82c 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -3,7 +3,7 @@ package com.iluwatar.eda.event; import com.iluwatar.eda.model.User; /** - * The {@link UserCreatedEvent} class should should be dispatched whenever a user has been created. + * The {@link UserCreatedEvent} should should be dispatched whenever a user has been created. * This class can be extended to contain details about the user has been created. In this example, * the entire {@link User} object is passed on as data with the event. */ diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java index f3bce8124..c07e83e7c 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -3,7 +3,7 @@ package com.iluwatar.eda.event; import com.iluwatar.eda.model.User; /** - * The {@link UserUpdatedEvent} class should should be dispatched whenever a user has been updated. + * The {@link UserUpdatedEvent} should should be dispatched whenever a user has been updated. * This class can be extended to contain details about the user has been updated. In this example, * the entire {@link User} object is passed on as data with the event. */ diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java deleted file mode 100644 index 1684a9641..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Channel.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.iluwatar.eda.framework; - -import com.iluwatar.eda.event.Event; - -/** - * Channels are delivery points for messages. Every {@link Channel} is responsible for a single type - * of message - */ -public interface Channel { - void dispatch(Event message); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java deleted file mode 100644 index 23fd6044f..000000000 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/DynamicRouter.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.iluwatar.eda.framework; - -/** - * A {@link DynamicRouter} is responsible for selecting the proper path of a {@link Message} - * Messages can be associated to Channels through the registerChannel method and dispatched by - * calling the dispatch method. - */ -public interface DynamicRouter { - - void registerChannel(Class contentType, Channel channel); - - void dispatch(E content); -} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java new file mode 100644 index 000000000..fef303937 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java @@ -0,0 +1,42 @@ +package com.iluwatar.eda.framework; + +import com.iluwatar.eda.event.Event; +import com.iluwatar.eda.framework.Handler; + +import java.util.HashMap; +import java.util.Map; + +/** + * Handles the routing of {@link Event} messages to associated handlers. + * A {@link HashMap} is used to store the association between events and their respective handlers. + * + */ +public class EventDispatcher { + + private Map, Handler> handlers; + + public EventDispatcher() { + handlers = new HashMap<>(); + } + + /** + * Links an {@link Event} to a specific {@link Handler}. + * + * @param eventType The {@link Event} to be registered + * @param handler The {@link Handler} that will be handling the {@link Event} + */ + public void registerChannel(Class eventType, + Handler handler) { + handlers.put(eventType, handler); + } + + /** + * Dispatches an {@link Event} depending on it's type. + * + * @param event The {@link Event} to be dispatched + */ + public void onEvent(Event event) { + handlers.get(event.getClass()).onEvent(event); + } + +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Handler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Handler.java new file mode 100644 index 000000000..cba2f08b2 --- /dev/null +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Handler.java @@ -0,0 +1,18 @@ +package com.iluwatar.eda.framework; + +import com.iluwatar.eda.event.Event; + +/** + * This interface can be implemented to handle different types of messages. + * Every handler is responsible for a single of type message + */ +public interface Handler { + + /** + * The onEvent method should implement and handle behavior related to the event. + * This can be as simple as calling another service to handle the event on publishing the event on + * a queue to be consumed by other sub systems. + * @param event the {@link Event} object to be handled. + */ + void onEvent(Event event); +} \ No newline at end of file diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java index 2f8acb343..f8f8c7dfc 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/Message.java @@ -2,8 +2,14 @@ package com.iluwatar.eda.framework; /** * A {@link Message} is an object with a specific type that is associated - * to a specific {@link Channel}. + * to a specific {@link Handler}. */ public interface Message { + + /** + * Returns the message type as a {@link Class} object. In this example the message type is + * used to handle events by their type. + * @return the message type as a {@link Class}. + */ Class getType(); } diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java index 49d209eb0..7db4a2d81 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserCreatedEventHandler.java @@ -2,16 +2,15 @@ package com.iluwatar.eda.handler; import com.iluwatar.eda.event.Event; import com.iluwatar.eda.event.UserCreatedEvent; -import com.iluwatar.eda.framework.Channel; -import com.iluwatar.eda.model.User; +import com.iluwatar.eda.framework.Handler; /** * Handles the {@link UserCreatedEvent} message. */ -public class UserCreatedEventHandler implements Channel { +public class UserCreatedEventHandler implements Handler { @Override - public void dispatch(Event message) { + public void onEvent(Event message) { UserCreatedEvent userCreatedEvent = (UserCreatedEvent) message; System.out.printf("User with %s has been Created!", userCreatedEvent.getUser().getUsername()); diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java index fd3a6d3ba..754a75c45 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/handler/UserUpdatedEventHandler.java @@ -1,17 +1,16 @@ package com.iluwatar.eda.handler; import com.iluwatar.eda.event.Event; -import com.iluwatar.eda.event.UserCreatedEvent; import com.iluwatar.eda.event.UserUpdatedEvent; -import com.iluwatar.eda.framework.Channel; +import com.iluwatar.eda.framework.Handler; /** * Handles the {@link UserUpdatedEvent} message. */ -public class UserUpdatedEventHandler implements Channel { +public class UserUpdatedEventHandler implements Handler { @Override - public void dispatch(Event message) { + public void onEvent(Event message) { UserUpdatedEvent userUpdatedEvent = (UserUpdatedEvent) message; System.out.printf("User with %s has been Updated!", userUpdatedEvent.getUser().getUsername()); diff --git a/event-driven-architecture/src/test/java/EventDrivenTest.java b/event-driven-architecture/src/test/java/EventDrivenTest.java deleted file mode 100644 index addc5fafa..000000000 --- a/event-driven-architecture/src/test/java/EventDrivenTest.java +++ /dev/null @@ -1,63 +0,0 @@ -import com.iluwatar.eda.EventDispatcher; -import com.iluwatar.eda.event.Event; -import com.iluwatar.eda.event.UserCreatedEvent; -import com.iluwatar.eda.event.UserUpdatedEvent; -import com.iluwatar.eda.handler.UserCreatedEventHandler; -import com.iluwatar.eda.handler.UserUpdatedEventHandler; -import com.iluwatar.eda.model.User; - -import org.junit.Test; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.junit.Assert.assertEquals; - - -/** - * Event Driven Pattern unit tests to assert and verify correct pattern behaviour - */ -public class EventDrivenTest { - - /** - * This unit test should register events and event handlers correctly with the event dispatcher - * and events should be dispatched accordingly. - */ - @Test - public void testEventDriverPattern() { - - EventDispatcher dispatcher = spy(new EventDispatcher()); - UserCreatedEventHandler userCreatedEventHandler = new UserCreatedEventHandler(); - UserUpdatedEventHandler userUpdatedEventHandler = new UserUpdatedEventHandler(); - dispatcher.registerChannel(UserCreatedEvent.class, userCreatedEventHandler); - dispatcher.registerChannel(UserUpdatedEvent.class, userUpdatedEventHandler); - - assertEquals("Two handlers must be registered", 2, dispatcher.getHandlers().size()); - assertEquals("UserCreatedEvent must return the UserCreatedEventHandler", - userCreatedEventHandler, - (UserCreatedEventHandler) dispatcher.getHandlers().get(UserCreatedEvent.class)); - assertEquals("UserUpdatedEvent must be registered to the UserUpdatedEventHandler", - userUpdatedEventHandler, - (UserUpdatedEventHandler) dispatcher.getHandlers().get(UserUpdatedEvent.class)); - - User user = new User("iluwatar"); - - UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); - UserUpdatedEvent userUpdatedEvent = new UserUpdatedEvent(user); - dispatcher.dispatch(userCreatedEvent); - dispatcher.dispatch(userUpdatedEvent); - - //verify that the events have been dispatched - verify(dispatcher).dispatch(userCreatedEvent); - verify(dispatcher).dispatch(userUpdatedEvent); - } - - /** - * This unit test should correctly return the {@link Event} class type when calling the - * {@link Event#getType() getType} method. - */ - @Test - public void testGetEventType() { - User user = new User("iluwatar"); - UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); - assertEquals(UserCreatedEvent.class, userCreatedEvent.getType()); - } -} diff --git a/event-driven-architecture/src/test/java/com/iluwatar/eda/event/UserCreatedEventTest.java b/event-driven-architecture/src/test/java/com/iluwatar/eda/event/UserCreatedEventTest.java new file mode 100644 index 000000000..108280bf1 --- /dev/null +++ b/event-driven-architecture/src/test/java/com/iluwatar/eda/event/UserCreatedEventTest.java @@ -0,0 +1,24 @@ +package com.iluwatar.eda.event; + +import com.iluwatar.eda.model.User; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * {@link UserCreatedEventTest} tests and verifies {@link Event} behaviour. + */ +public class UserCreatedEventTest { + + /** + * This unit test should correctly return the {@link Event} class type when calling the + * {@link Event#getType() getType} method. + */ + @Test + public void testGetEventType() { + User user = new User("iluwatar"); + UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); + assertEquals(UserCreatedEvent.class, userCreatedEvent.getType()); + } +} diff --git a/event-driven-architecture/src/test/java/com/iluwatar/eda/framework/EventDispatcherTest.java b/event-driven-architecture/src/test/java/com/iluwatar/eda/framework/EventDispatcherTest.java new file mode 100644 index 000000000..163ffed6e --- /dev/null +++ b/event-driven-architecture/src/test/java/com/iluwatar/eda/framework/EventDispatcherTest.java @@ -0,0 +1,50 @@ +package com.iluwatar.eda.framework; + +import com.iluwatar.eda.framework.EventDispatcher; +import com.iluwatar.eda.event.UserCreatedEvent; +import com.iluwatar.eda.event.UserUpdatedEvent; +import com.iluwatar.eda.handler.UserCreatedEventHandler; +import com.iluwatar.eda.handler.UserUpdatedEventHandler; +import com.iluwatar.eda.model.User; + +import org.junit.Test; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +/** + * Event Dispatcher unit tests to assert and verify correct event dispatcher behaviour + */ +public class EventDispatcherTest { + + /** + * This unit test should register events and event handlers correctly with the event dispatcher + * and events should be dispatched accordingly. + */ + @Test + public void testEventDriverPattern() { + + EventDispatcher dispatcher = spy(new EventDispatcher()); + UserCreatedEventHandler userCreatedEventHandler = spy(new UserCreatedEventHandler()); + UserUpdatedEventHandler userUpdatedEventHandler = spy(new UserUpdatedEventHandler()); + dispatcher.registerChannel(UserCreatedEvent.class, userCreatedEventHandler); + dispatcher.registerChannel(UserUpdatedEvent.class, userUpdatedEventHandler); + + User user = new User("iluwatar"); + + UserCreatedEvent userCreatedEvent = new UserCreatedEvent(user); + UserUpdatedEvent userUpdatedEvent = new UserUpdatedEvent(user); + + //fire a userCreatedEvent and verify that userCreatedEventHandler has been invoked. + dispatcher.onEvent(userCreatedEvent); + verify(userCreatedEventHandler).onEvent(userCreatedEvent); + verify(dispatcher).onEvent(userCreatedEvent); + + //fire a userCreatedEvent and verify that userUpdatedEventHandler has been invoked. + dispatcher.onEvent(userUpdatedEvent); + verify(userUpdatedEventHandler).onEvent(userUpdatedEvent); + verify(dispatcher).onEvent(userUpdatedEvent); + } + + +} From 2aa20b7445c27caf540af62ca1be60dcb2ddf631 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Tue, 1 Dec 2015 23:33:26 +0100 Subject: [PATCH 012/106] #113 Event Driven Architecture Adds various changes including : - Fixes to Javadoc --- .../src/main/java/com/iluwatar/eda/event/Event.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java index 9ef3dd7db..bcf78f275 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/Event.java @@ -17,7 +17,7 @@ public class Event implements Message { /** * Returns the event type as a {@link Class} object * In this example, this method is used by the {@link EventDispatcher} to - * onEvent events depending on their type. + * dispatch events depending on their type. * * @return the Event type as a {@link Class}. */ From 0b46a9985df028bb0445bd52df0708d6bc2dea98 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Wed, 2 Dec 2015 01:39:20 +0100 Subject: [PATCH 013/106] #113 Event Driven Architecture Updated index.md with eda uses --- event-driven-architecture/index.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/event-driven-architecture/index.md b/event-driven-architecture/index.md index 0a4be0bb6..f7b586c88 100644 --- a/event-driven-architecture/index.md +++ b/event-driven-architecture/index.md @@ -16,13 +16,10 @@ permalink: /patterns/event-driven-architecture **Real world examples:** -* A Loan Application has been accepted/rejected (Commercial Business). -* A new Rostering Schedule is ready for distribution to all crew (Airline Management System). -* An Illegal Trade Pattern has been detected (Trading Fraud Detection System). -* A simulated car has hits another simulated car (Commercial Racing Game). -* A robot has reached its destination (Real Time Warehouse Management System). -* A HTML message has been received (Web Server). -* A key has been pressed (Text Editor). +* SendGrid, an email API, sends events whenever an email is processed, delivered, opened etc... (https://sendgrid.com/docs/API_Reference/Webhooks/event.html) +* Chargify, a billing API, exposes payment activity through various events (https://docs.chargify.com/api-events) +* Amazon's AWS Lambda, lets you execute code in response to such as changes to Amazon S3 buckets, updates to an Amazon DynamoDB table, or custom events generated by your applications or devices. (https://aws.amazon.com/lambda) +* MySQL runs triggers based on events such as inserts and update events happening on database tables. **Credits:** From 898f3a428c508418e1fc2ca27c793bd395e7a7e0 Mon Sep 17 00:00:00 2001 From: cfarrugia Date: Wed, 2 Dec 2015 01:43:34 +0100 Subject: [PATCH 014/106] #113 Event Driven Architecture Fixed a typo in index.md --- event-driven-architecture/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event-driven-architecture/index.md b/event-driven-architecture/index.md index f7b586c88..40d84004d 100644 --- a/event-driven-architecture/index.md +++ b/event-driven-architecture/index.md @@ -18,7 +18,7 @@ permalink: /patterns/event-driven-architecture * SendGrid, an email API, sends events whenever an email is processed, delivered, opened etc... (https://sendgrid.com/docs/API_Reference/Webhooks/event.html) * Chargify, a billing API, exposes payment activity through various events (https://docs.chargify.com/api-events) -* Amazon's AWS Lambda, lets you execute code in response to such as changes to Amazon S3 buckets, updates to an Amazon DynamoDB table, or custom events generated by your applications or devices. (https://aws.amazon.com/lambda) +* Amazon's AWS Lambda, lets you execute code in response to events such as changes to Amazon S3 buckets, updates to an Amazon DynamoDB table, or custom events generated by your applications or devices. (https://aws.amazon.com/lambda) * MySQL runs triggers based on events such as inserts and update events happening on database tables. **Credits:** From 5948a82cf2b39bb74bde5b58a217924a2da8c6e5 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 19 Dec 2015 11:52:20 +0100 Subject: [PATCH 015/106] Added tests for layers pattern --- layers/pom.xml | 5 + .../layers/CakeBakingServiceImpl.java | 8 +- .../java/com/iluwatar/layers/CakeInfo.java | 2 +- .../com/iluwatar/layers/CakeLayerInfo.java | 2 +- .../java/com/iluwatar/layers/CakeTopping.java | 2 +- .../com/iluwatar/layers/CakeToppingInfo.java | 2 +- .../layers/CakeBakingExceptionTest.java | 30 ++++ .../layers/CakeBakingServiceImplTest.java | 159 ++++++++++++++++++ .../java/com/iluwatar/layers/CakeTest.java | 97 +++++++++++ .../com/iluwatar/layers/CakeViewImplTest.java | 48 ++++++ .../java/com/iluwatar/layers/StdOutTest.java | 54 ++++++ 11 files changed, 401 insertions(+), 8 deletions(-) create mode 100644 layers/src/test/java/com/iluwatar/layers/CakeBakingExceptionTest.java create mode 100644 layers/src/test/java/com/iluwatar/layers/CakeBakingServiceImplTest.java create mode 100644 layers/src/test/java/com/iluwatar/layers/CakeTest.java create mode 100644 layers/src/test/java/com/iluwatar/layers/CakeViewImplTest.java create mode 100644 layers/src/test/java/com/iluwatar/layers/StdOutTest.java diff --git a/layers/pom.xml b/layers/pom.xml index 23b1db192..438c6c5d4 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -32,5 +32,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/layers/src/main/java/com/iluwatar/layers/CakeBakingServiceImpl.java b/layers/src/main/java/com/iluwatar/layers/CakeBakingServiceImpl.java index a519ec2ce..79917842d 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeBakingServiceImpl.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeBakingServiceImpl.java @@ -30,9 +30,9 @@ public class CakeBakingServiceImpl implements CakeBakingService { @Override public void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException { - List allToppings = getAvailableToppings(); - List matchingToppings = - allToppings.stream().filter((t) -> t.name.equals(cakeInfo.cakeToppingInfo.name)) + List allToppings = getAvailableToppingEntities(); + List matchingToppings = + allToppings.stream().filter((t) -> t.getName().equals(cakeInfo.cakeToppingInfo.name)) .collect(Collectors.toList()); if (matchingToppings.isEmpty()) { throw new CakeBakingException(String.format("Topping %s is not available", @@ -50,7 +50,7 @@ public class CakeBakingServiceImpl implements CakeBakingService { } } CakeToppingDao toppingBean = context.getBean(CakeToppingDao.class); - CakeTopping topping = toppingBean.findOne(matchingToppings.iterator().next().id.get()); + CakeTopping topping = toppingBean.findOne(matchingToppings.iterator().next().getId()); CakeDao cakeBean = context.getBean(CakeDao.class); Cake cake = new Cake(); cake.setTopping(topping); diff --git a/layers/src/main/java/com/iluwatar/layers/CakeInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeInfo.java index f60ee9a14..21b7d9ed8 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeInfo.java @@ -34,7 +34,7 @@ public class CakeInfo { @Override public String toString() { - return String.format("CakeInfo id=%d topping=%s layers=%s totalCalories=%d", id.get(), + return String.format("CakeInfo id=%d topping=%s layers=%s totalCalories=%d", id.orElse(-1L), cakeToppingInfo, cakeLayerInfos, calculateTotalCalories()); } } diff --git a/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java index 3dff379da..dca81faaa 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java @@ -27,6 +27,6 @@ public class CakeLayerInfo { @Override public String toString() { - return String.format("CakeLayerInfo id=%d name=%s calories=%d", id.get(), name, calories); + return String.format("CakeLayerInfo id=%d name=%s calories=%d", id.orElse(-1L), name, calories); } } diff --git a/layers/src/main/java/com/iluwatar/layers/CakeTopping.java b/layers/src/main/java/com/iluwatar/layers/CakeTopping.java index 6dc9c45fc..9f2107f1e 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeTopping.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeTopping.java @@ -58,7 +58,7 @@ public class CakeTopping { @Override public String toString() { - return String.format("id=%s name=%s calories=%d", name, calories); + return String.format("id=%s name=%s calories=%d", id, name, calories); } public Cake getCake() { diff --git a/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java index 4e432ec44..befebc8fe 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java @@ -27,6 +27,6 @@ public class CakeToppingInfo { @Override public String toString() { - return String.format("CakeToppingInfo id=%d name=%s calories=%d", id.get(), name, calories); + return String.format("CakeToppingInfo id=%d name=%s calories=%d", id.orElse(-1L), name, calories); } } diff --git a/layers/src/test/java/com/iluwatar/layers/CakeBakingExceptionTest.java b/layers/src/test/java/com/iluwatar/layers/CakeBakingExceptionTest.java new file mode 100644 index 000000000..87381a309 --- /dev/null +++ b/layers/src/test/java/com/iluwatar/layers/CakeBakingExceptionTest.java @@ -0,0 +1,30 @@ +package com.iluwatar.layers; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** + * Date: 12/15/15 - 7:57 PM + * + * @author Jeroen Meulemeester + */ +public class CakeBakingExceptionTest { + + @Test + public void testConstructor() throws Exception { + final CakeBakingException exception = new CakeBakingException(); + assertNull(exception.getMessage()); + assertNull(exception.getCause()); + } + + @Test + public void testConstructorWithMessage() throws Exception { + final String expectedMessage = "message"; + final CakeBakingException exception = new CakeBakingException(expectedMessage); + assertEquals(expectedMessage, exception.getMessage()); + assertNull(exception.getCause()); + } + +} diff --git a/layers/src/test/java/com/iluwatar/layers/CakeBakingServiceImplTest.java b/layers/src/test/java/com/iluwatar/layers/CakeBakingServiceImplTest.java new file mode 100644 index 000000000..11caab9ea --- /dev/null +++ b/layers/src/test/java/com/iluwatar/layers/CakeBakingServiceImplTest.java @@ -0,0 +1,159 @@ +package com.iluwatar.layers; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Date: 12/15/15 - 9:55 PM + * + * @author Jeroen Meulemeester + */ +public class CakeBakingServiceImplTest { + + @Test + public void testLayers() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final List initialLayers = service.getAvailableLayers(); + assertNotNull(initialLayers); + assertTrue(initialLayers.isEmpty()); + + service.saveNewLayer(new CakeLayerInfo("Layer1", 1000)); + service.saveNewLayer(new CakeLayerInfo("Layer2", 2000)); + + final List availableLayers = service.getAvailableLayers(); + assertNotNull(availableLayers); + assertEquals(2, availableLayers.size()); + for (final CakeLayerInfo layer : availableLayers) { + assertNotNull(layer.id); + assertNotNull(layer.name); + assertNotNull(layer.toString()); + assertTrue(layer.calories > 0); + } + + } + + @Test + public void testToppings() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final List initialToppings = service.getAvailableToppings(); + assertNotNull(initialToppings); + assertTrue(initialToppings.isEmpty()); + + service.saveNewTopping(new CakeToppingInfo("Topping1", 1000)); + service.saveNewTopping(new CakeToppingInfo("Topping2", 2000)); + + final List availableToppings = service.getAvailableToppings(); + assertNotNull(availableToppings); + assertEquals(2, availableToppings.size()); + for (final CakeToppingInfo topping : availableToppings) { + assertNotNull(topping.id); + assertNotNull(topping.name); + assertNotNull(topping.toString()); + assertTrue(topping.calories > 0); + } + + } + + @Test + public void testBakeCakes() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final List initialCakes = service.getAllCakes(); + assertNotNull(initialCakes); + assertTrue(initialCakes.isEmpty()); + + final CakeToppingInfo topping1 = new CakeToppingInfo("Topping1", 1000); + final CakeToppingInfo topping2 = new CakeToppingInfo("Topping2", 2000); + service.saveNewTopping(topping1); + service.saveNewTopping(topping2); + + final CakeLayerInfo layer1 = new CakeLayerInfo("Layer1", 1000); + final CakeLayerInfo layer2 = new CakeLayerInfo("Layer2", 2000); + final CakeLayerInfo layer3 = new CakeLayerInfo("Layer3", 2000); + service.saveNewLayer(layer1); + service.saveNewLayer(layer2); + service.saveNewLayer(layer3); + + service.bakeNewCake(new CakeInfo(topping1, Arrays.asList(layer1, layer2))); + service.bakeNewCake(new CakeInfo(topping2, Collections.singletonList(layer3))); + + final List allCakes = service.getAllCakes(); + assertNotNull(allCakes); + assertEquals(2, allCakes.size()); + for (final CakeInfo cakeInfo : allCakes) { + assertNotNull(cakeInfo.id); + assertNotNull(cakeInfo.cakeToppingInfo); + assertNotNull(cakeInfo.cakeLayerInfos); + assertNotNull(cakeInfo.toString()); + assertFalse(cakeInfo.cakeLayerInfos.isEmpty()); + assertTrue(cakeInfo.calculateTotalCalories() > 0); + } + + } + + @Test(expected = CakeBakingException.class) + public void testBakeCakeMissingTopping() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final CakeLayerInfo layer1 = new CakeLayerInfo("Layer1", 1000); + final CakeLayerInfo layer2 = new CakeLayerInfo("Layer2", 2000); + service.saveNewLayer(layer1); + service.saveNewLayer(layer2); + + final CakeToppingInfo missingTopping = new CakeToppingInfo("Topping1", 1000); + service.bakeNewCake(new CakeInfo(missingTopping, Arrays.asList(layer1, layer2))); + } + + @Test(expected = CakeBakingException.class) + public void testBakeCakeMissingLayer() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final List initialCakes = service.getAllCakes(); + assertNotNull(initialCakes); + assertTrue(initialCakes.isEmpty()); + + final CakeToppingInfo topping1 = new CakeToppingInfo("Topping1", 1000); + service.saveNewTopping(topping1); + + final CakeLayerInfo layer1 = new CakeLayerInfo("Layer1", 1000); + service.saveNewLayer(layer1); + + final CakeLayerInfo missingLayer = new CakeLayerInfo("Layer2", 2000); + service.bakeNewCake(new CakeInfo(topping1, Arrays.asList(layer1, missingLayer))); + + } + + @Test(expected = CakeBakingException.class) + public void testBakeCakesUsedLayer() throws CakeBakingException { + final CakeBakingServiceImpl service = new CakeBakingServiceImpl(); + + final List initialCakes = service.getAllCakes(); + assertNotNull(initialCakes); + assertTrue(initialCakes.isEmpty()); + + final CakeToppingInfo topping1 = new CakeToppingInfo("Topping1", 1000); + final CakeToppingInfo topping2 = new CakeToppingInfo("Topping2", 2000); + service.saveNewTopping(topping1); + service.saveNewTopping(topping2); + + final CakeLayerInfo layer1 = new CakeLayerInfo("Layer1", 1000); + final CakeLayerInfo layer2 = new CakeLayerInfo("Layer2", 2000); + service.saveNewLayer(layer1); + service.saveNewLayer(layer2); + + service.bakeNewCake(new CakeInfo(topping1, Arrays.asList(layer1, layer2))); + service.bakeNewCake(new CakeInfo(topping2, Collections.singletonList(layer2))); + + } + +} diff --git a/layers/src/test/java/com/iluwatar/layers/CakeTest.java b/layers/src/test/java/com/iluwatar/layers/CakeTest.java new file mode 100644 index 000000000..30d1df0fc --- /dev/null +++ b/layers/src/test/java/com/iluwatar/layers/CakeTest.java @@ -0,0 +1,97 @@ +package com.iluwatar.layers; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Date: 12/15/15 - 8:02 PM + * + * @author Jeroen Meulemeester + */ +public class CakeTest { + + @Test + public void testSetId() { + final Cake cake = new Cake(); + assertNull(cake.getId()); + + final Long expectedId = Long.valueOf(1234L); + cake.setId(expectedId); + assertEquals(expectedId, cake.getId()); + } + + @Test + public void testSetTopping() { + final Cake cake = new Cake(); + assertNull(cake.getTopping()); + + final CakeTopping expectedTopping = new CakeTopping("DummyTopping", 1000); + cake.setTopping(expectedTopping); + assertEquals(expectedTopping, cake.getTopping()); + } + + @Test + public void testSetLayers() { + final Cake cake = new Cake(); + assertNotNull(cake.getLayers()); + assertTrue(cake.getLayers().isEmpty()); + + final Set expectedLayers = new HashSet<>(); + expectedLayers.add(new CakeLayer("layer1", 1000)); + expectedLayers.add(new CakeLayer("layer2", 2000)); + expectedLayers.add(new CakeLayer("layer3", 3000)); + + cake.setLayers(expectedLayers); + assertEquals(expectedLayers, cake.getLayers()); + } + + @Test + public void testAddLayer() { + final Cake cake = new Cake(); + assertNotNull(cake.getLayers()); + assertTrue(cake.getLayers().isEmpty()); + + final Set initialLayers = new HashSet<>(); + initialLayers.add(new CakeLayer("layer1", 1000)); + initialLayers.add(new CakeLayer("layer2", 2000)); + + cake.setLayers(initialLayers); + assertEquals(initialLayers, cake.getLayers()); + + final CakeLayer newLayer = new CakeLayer("layer3", 3000); + cake.addLayer(newLayer); + + final Set expectedLayers = new HashSet<>(); + expectedLayers.addAll(initialLayers); + expectedLayers.addAll(initialLayers); + expectedLayers.add(newLayer); + assertEquals(expectedLayers, cake.getLayers()); + } + + @Test + public void testToString() { + final CakeTopping topping = new CakeTopping("topping", 20); + topping.setId(2345L); + + final CakeLayer layer = new CakeLayer("layer", 100); + layer.setId(3456L); + + final Cake cake = new Cake(); + cake.setId(1234L); + cake.setTopping(topping); + cake.addLayer(layer); + + final String expected = "id=1234 topping=id=2345 name=topping calories=20 " + + "layers=[id=3456 name=layer calories=100]"; + assertEquals(expected, cake.toString()); + + } + +} diff --git a/layers/src/test/java/com/iluwatar/layers/CakeViewImplTest.java b/layers/src/test/java/com/iluwatar/layers/CakeViewImplTest.java new file mode 100644 index 000000000..1dc9a4d01 --- /dev/null +++ b/layers/src/test/java/com/iluwatar/layers/CakeViewImplTest.java @@ -0,0 +1,48 @@ +package com.iluwatar.layers; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +/** + * Date: 12/15/15 - 10:04 PM + * + * @author Jeroen Meulemeester + */ +public class CakeViewImplTest extends StdOutTest { + + /** + * Verify if the cake view renders the expected result + */ + @Test + public void testRender() { + + final List layers = new ArrayList<>(); + layers.add(new CakeLayerInfo("layer1", 1000)); + layers.add(new CakeLayerInfo("layer2", 2000)); + layers.add(new CakeLayerInfo("layer3", 3000)); + + final List cakes = new ArrayList<>(); + final CakeInfo cake = new CakeInfo(new CakeToppingInfo("topping", 1000), layers); + cakes.add(cake); + + final CakeBakingService bakingService = mock(CakeBakingService.class); + when(bakingService.getAllCakes()).thenReturn(cakes); + + final CakeViewImpl cakeView = new CakeViewImpl(bakingService); + + verifyZeroInteractions(getStdOutMock()); + + cakeView.render(); + verify(getStdOutMock(), times(1)).println(cake); + + } + +} diff --git a/layers/src/test/java/com/iluwatar/layers/StdOutTest.java b/layers/src/test/java/com/iluwatar/layers/StdOutTest.java new file mode 100644 index 000000000..fe72bbb8a --- /dev/null +++ b/layers/src/test/java/com/iluwatar/layers/StdOutTest.java @@ -0,0 +1,54 @@ +package com.iluwatar.layers; + +import org.junit.After; +import org.junit.Before; + +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; + +/** + * Date: 12/10/15 - 8:37 PM + * + * @author Jeroen Meulemeester + */ +public abstract class StdOutTest { + + /** + * The mocked standard out {@link PrintStream}, required since the actions of the views don't have + * any influence on any other accessible objects, except for writing to std-out using {@link + * System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * Get the mocked stdOut {@link PrintStream} + * + * @return The stdOut print stream mock, renewed before each test + */ + final PrintStream getStdOutMock() { + return this.stdOutMock; + } + +} From 2c82bd945096184309750ab212603fe16d20dad4 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 19 Dec 2015 13:17:28 +0100 Subject: [PATCH 016/106] Added tests for lazy-loading pattern --- .../lazy/loading/AbstractHolderTest.java | 41 +++++++++++++++ .../lazy/loading/HolderNaiveTest.java | 26 ++++++++++ .../lazy/loading/HolderThreadSafeTest.java | 51 ++++++------------- .../lazy/loading/Java8HolderTest.java | 40 +++++++++++++++ 4 files changed, 123 insertions(+), 35 deletions(-) create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java create mode 100644 lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java new file mode 100644 index 000000000..99523cd0a --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AbstractHolderTest.java @@ -0,0 +1,41 @@ +package com.iluwatar.lazy.loading; + +import org.junit.Test; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertSame; +import static junit.framework.TestCase.assertNull; + +/** + * Date: 12/19/15 - 11:58 AM + * + * @author Jeroen Meulemeester + */ +public abstract class AbstractHolderTest { + + /** + * Get the internal state of the holder value + * + * @return The internal value + */ + abstract Heavy getInternalHeavyValue() throws Exception; + + /** + * Request a lazy loaded {@link Heavy} object from the holder. + * + * @return The lazy loaded {@link Heavy} object + */ + abstract Heavy getHeavy() throws Exception; + + /** + * This test shows that the heavy field is not instantiated until the method getHeavy is called + */ + @Test(timeout = 3000) + public void testGetHeavy() throws Exception { + assertNull(getInternalHeavyValue()); + assertNotNull(getHeavy()); + assertNotNull(getInternalHeavyValue()); + assertSame(getHeavy(), getInternalHeavyValue()); + } + +} diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java new file mode 100644 index 000000000..2c539e8ca --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderNaiveTest.java @@ -0,0 +1,26 @@ +package com.iluwatar.lazy.loading; + +import java.lang.reflect.Field; + +/** + * Date: 12/19/15 - 12:05 PM + * + * @author Jeroen Meulemeester + */ +public class HolderNaiveTest extends AbstractHolderTest { + + private final HolderNaive holder = new HolderNaive(); + + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = HolderNaive.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + return (Heavy) holderField.get(this.holder); + } + + @Override + Heavy getHeavy() { + return holder.getHeavy(); + } + +} \ No newline at end of file diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java index d827f186b..f6aed73b7 100644 --- a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/HolderThreadSafeTest.java @@ -1,45 +1,26 @@ package com.iluwatar.lazy.loading; -import org.junit.Test; - import java.lang.reflect.Field; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - /** - * Using reflection this test shows that the heavy field is not instantiated until the method - * getHeavy is called + * Date: 12/19/15 - 12:19 PM * - * Created by jones on 11/10/2015. + * @author Jeroen Meulemeester */ -public class HolderThreadSafeTest { +public class HolderThreadSafeTest extends AbstractHolderTest { - @Test - public void test() throws IllegalAccessException { - HolderThreadSafe hts = new HolderThreadSafe(); + private final HolderThreadSafe holder = new HolderThreadSafe(); - { - // first call is null - Field[] ff = HolderThreadSafe.class.getDeclaredFields(); - for (Field f : ff) { - f.setAccessible(true); - } - - assertNull(ff[0].get(hts)); - } - - // now it is lazily loaded - hts.getHeavy(); - - { - // now it is not null - call via reflection so that the test is the same before and after - Field[] ff = HolderThreadSafe.class.getDeclaredFields(); - for (Field f : ff) { - f.setAccessible(true); - } - - assertNotNull(ff[0].get(hts)); - } + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = HolderThreadSafe.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + return (Heavy) holderField.get(this.holder); } -} + + @Override + Heavy getHeavy() throws Exception { + return this.holder.getHeavy(); + } + +} \ No newline at end of file diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java new file mode 100644 index 000000000..aed9a054e --- /dev/null +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/Java8HolderTest.java @@ -0,0 +1,40 @@ +package com.iluwatar.lazy.loading; + +import java.lang.reflect.Field; +import java.util.function.Supplier; + +/** + * Date: 12/19/15 - 12:27 PM + * + * @author Jeroen Meulemeester + */ +public class Java8HolderTest extends AbstractHolderTest { + + private final Java8Holder holder = new Java8Holder(); + + + @Override + Heavy getInternalHeavyValue() throws Exception { + final Field holderField = Java8Holder.class.getDeclaredField("heavy"); + holderField.setAccessible(true); + + final Supplier supplier = (Supplier) holderField.get(this.holder); + final Class supplierClass = supplier.getClass(); + + // This is a little fishy, but I don't know another way to test this: + // The lazy holder is at first a lambda, but gets replaced with a new supplier after loading ... + if (supplierClass.isLocalClass()) { + final Field instanceField = supplierClass.getDeclaredField("heavyInstance"); + instanceField.setAccessible(true); + return (Heavy) instanceField.get(supplier); + } else { + return null; + } + } + + @Override + Heavy getHeavy() throws Exception { + return holder.getHeavy(); + } + +} \ No newline at end of file From 719f80a0d66e3e5977b21bb7f057037fe7323041 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 20 Dec 2015 00:00:07 +0100 Subject: [PATCH 017/106] Added tests for mediator pattern --- mediator/pom.xml | 5 + .../com/iluwatar/mediator/PartyImplTest.java | 41 ++++++ .../iluwatar/mediator/PartyMemberTest.java | 128 ++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java create mode 100644 mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java diff --git a/mediator/pom.xml b/mediator/pom.xml index 0e9bff5d1..58fb73628 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java new file mode 100644 index 000000000..992662fb2 --- /dev/null +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java @@ -0,0 +1,41 @@ +package com.iluwatar.mediator; + +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/19/15 - 10:00 PM + * + * @author Jeroen Meulemeester + */ +public class PartyImplTest { + + /** + * Verify if a member is notified when it's joining a party. Generate an action and see if the + * other member gets it. Also check members don't get their own actions. + */ + @Test + public void testPartyAction() { + final PartyMember partyMember1 = mock(PartyMember.class); + final PartyMember partyMember2 = mock(PartyMember.class); + + final PartyImpl party = new PartyImpl(); + party.addMember(partyMember1); + party.addMember(partyMember2); + + verify(partyMember1).joinedParty(party); + verify(partyMember2).joinedParty(party); + + party.act(partyMember1, Action.GOLD); + verifyZeroInteractions(partyMember1); + verify(partyMember2).partyAction(Action.GOLD); + + verifyNoMoreInteractions(partyMember1, partyMember2); + + } + +} diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java new file mode 100644 index 000000000..31b7222e9 --- /dev/null +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java @@ -0,0 +1,128 @@ +package com.iluwatar.mediator; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Supplier; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/19/15 - 10:13 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class PartyMemberTest { + + @Parameterized.Parameters + public static Collection[]> data() { + return Arrays.asList( + new Supplier[]{Hobbit::new}, + new Supplier[]{Hunter::new}, + new Supplier[]{Rogue::new}, + new Supplier[]{Wizard::new} + ); + } + + /** + * The mocked standard out {@link PrintStream}, required since some actions on a {@link + * PartyMember} have any influence on any other accessible objects, except for writing to std-out + * using {@link System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * The factory, used to create a new instance of the tested party member + */ + private final Supplier memberSupplier; + + /** + * Create a new test instance, using the given {@link PartyMember} factory + * + * @param memberSupplier The party member factory + */ + public PartyMemberTest(final Supplier memberSupplier) { + this.memberSupplier = memberSupplier; + } + + /** + * Verify if a party action triggers the correct output to the std-Out + */ + @Test + public void testPartyAction() { + final PartyMember member = this.memberSupplier.get(); + + for (final Action action : Action.values()) { + member.partyAction(action); + verify(this.stdOutMock).println(member.toString() + " " + action.getDescription()); + } + + verifyNoMoreInteractions(this.stdOutMock); + } + + /** + * Verify if a member action triggers the expected interactions with the party class + */ + @Test + public void testAct() { + final PartyMember member = this.memberSupplier.get(); + + member.act(Action.GOLD); + verifyZeroInteractions(this.stdOutMock); + + final Party party = mock(Party.class); + member.joinedParty(party); + verify(this.stdOutMock).println(member.toString() + " joins the party"); + + for (final Action action : Action.values()) { + member.act(action); + verify(this.stdOutMock).println(member.toString() + " " + action.toString()); + verify(party).act(member, action); + } + + verifyNoMoreInteractions(party, this.stdOutMock); + } + + /** + * Verify if {@link PartyMember#toString()} generate the expected output + */ + @Test + public void testToString() throws Exception { + final PartyMember member = this.memberSupplier.get(); + final Class memberClass = member.getClass(); + assertEquals(memberClass.getSimpleName(), member.toString()); + } + +} From a57a71b09c63ba9a24c89b00ae7192176914ac3d Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 20 Dec 2015 10:39:02 +0100 Subject: [PATCH 018/106] Added tests for memento pattern --- .../java/com/iluwatar/memento/StarTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 memento/src/test/java/com/iluwatar/memento/StarTest.java diff --git a/memento/src/test/java/com/iluwatar/memento/StarTest.java b/memento/src/test/java/com/iluwatar/memento/StarTest.java new file mode 100644 index 000000000..b5c7d9be0 --- /dev/null +++ b/memento/src/test/java/com/iluwatar/memento/StarTest.java @@ -0,0 +1,75 @@ +package com.iluwatar.memento; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Date: 12/20/15 - 10:08 AM + * + * @author Jeroen Meulemeester + */ +public class StarTest { + + /** + * Verify the stages of a dying sun, without going back in time + */ + @Test + public void testTimePasses() { + final Star star = new Star(StarType.SUN, 1, 2); + assertEquals("sun age: 1 years mass: 2 tons", star.toString()); + + star.timePasses(); + assertEquals("red giant age: 2 years mass: 16 tons", star.toString()); + + star.timePasses(); + assertEquals("white dwarf age: 4 years mass: 128 tons", star.toString()); + + star.timePasses(); + assertEquals("supernova age: 8 years mass: 1024 tons", star.toString()); + + star.timePasses(); + assertEquals("dead star age: 16 years mass: 8192 tons", star.toString()); + + star.timePasses(); + assertEquals("dead star age: 64 years mass: 0 tons", star.toString()); + + star.timePasses(); + assertEquals("dead star age: 256 years mass: 0 tons", star.toString()); + } + + /** + * Verify some stage of a dying sun, but go back in time to test the memento + */ + @Test + public void testSetMemento() { + final Star star = new Star(StarType.SUN, 1, 2); + final StarMemento firstMemento = star.getMemento(); + assertEquals("sun age: 1 years mass: 2 tons", star.toString()); + + star.timePasses(); + final StarMemento secondMemento = star.getMemento(); + assertEquals("red giant age: 2 years mass: 16 tons", star.toString()); + + star.timePasses(); + final StarMemento thirdMemento = star.getMemento(); + assertEquals("white dwarf age: 4 years mass: 128 tons", star.toString()); + + star.timePasses(); + assertEquals("supernova age: 8 years mass: 1024 tons", star.toString()); + + star.setMemento(thirdMemento); + assertEquals("white dwarf age: 4 years mass: 128 tons", star.toString()); + + star.timePasses(); + assertEquals("supernova age: 8 years mass: 1024 tons", star.toString()); + + star.setMemento(secondMemento); + assertEquals("red giant age: 2 years mass: 16 tons", star.toString()); + + star.setMemento(firstMemento); + assertEquals("sun age: 1 years mass: 2 tons", star.toString()); + + } + +} From 69c93746692a1bc3a1d0ec060f9b8ee650878cee Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 20 Dec 2015 14:31:36 +0100 Subject: [PATCH 019/106] Added tests for model-view-controller pattern --- model-view-controller/pom.xml | 5 + .../view/controller/GiantControllerTest.java | 100 ++++++++++++++++++ .../model/view/controller/GiantModelTest.java | 56 ++++++++++ .../model/view/controller/GiantViewTest.java | 64 +++++++++++ 4 files changed, 225 insertions(+) create mode 100644 model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java create mode 100644 model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java create mode 100644 model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index 8e5d3d9e2..a892f836e 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java new file mode 100644 index 000000000..0090f2d1d --- /dev/null +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java @@ -0,0 +1,100 @@ +package com.iluwatar.model.view.controller; + +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/20/15 - 2:19 PM + * + * @author Jeroen Meulemeester + */ +public class GiantControllerTest { + + /** + * Verify if the controller passes the health level through to the model and vice versa + */ + @Test + public void testSetHealth() { + final GiantModel model = mock(GiantModel.class); + final GiantView view = mock(GiantView.class); + final GiantController controller = new GiantController(model, view); + + verifyZeroInteractions(model, view); + + for (final Health health : Health.values()) { + controller.setHealth(health); + verify(model).setHealth(health); + verifyZeroInteractions(view); + } + + controller.getHealth(); + verify(model).getHealth(); + + verifyNoMoreInteractions(model, view); + } + + /** + * Verify if the controller passes the fatigue level through to the model and vice versa + */ + @Test + public void testSetFatigue() { + final GiantModel model = mock(GiantModel.class); + final GiantView view = mock(GiantView.class); + final GiantController controller = new GiantController(model, view); + + verifyZeroInteractions(model, view); + + for (final Fatigue fatigue : Fatigue.values()) { + controller.setFatigue(fatigue); + verify(model).setFatigue(fatigue); + verifyZeroInteractions(view); + } + + controller.getFatigue(); + verify(model).getFatigue(); + + verifyNoMoreInteractions(model, view); + } + + /** + * Verify if the controller passes the nourishment level through to the model and vice versa + */ + @Test + public void testSetNourishment() { + final GiantModel model = mock(GiantModel.class); + final GiantView view = mock(GiantView.class); + final GiantController controller = new GiantController(model, view); + + verifyZeroInteractions(model, view); + + for (final Nourishment nourishment : Nourishment.values()) { + controller.setNourishment(nourishment); + verify(model).setNourishment(nourishment); + verifyZeroInteractions(view); + } + + controller.getNourishment(); + verify(model).getNourishment(); + + verifyNoMoreInteractions(model, view); + } + + @Test + public void testUpdateView() { + final GiantModel model = mock(GiantModel.class); + final GiantView view = mock(GiantView.class); + final GiantController controller = new GiantController(model, view); + + verifyZeroInteractions(model, view); + + controller.updateView(); + verify(view).displayGiant(model); + + verifyNoMoreInteractions(model, view); + } + +} \ No newline at end of file diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java new file mode 100644 index 000000000..9513a62ec --- /dev/null +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java @@ -0,0 +1,56 @@ +package com.iluwatar.model.view.controller; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Date: 12/20/15 - 2:10 PM + * + * @author Jeroen Meulemeester + */ +public class GiantModelTest { + + /** + * Verify if the health value is set properly though the constructor and setter + */ + @Test + public void testSetHealth() { + final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + assertEquals(Health.HEALTHY, model.getHealth()); + for (final Health health : Health.values()) { + model.setHealth(health); + assertEquals(health, model.getHealth()); + assertEquals("The giant looks " + health.toString() + ", alert and saturated.", model.toString()); + } + } + + /** + * Verify if the fatigue level is set properly though the constructor and setter + */ + @Test + public void testSetFatigue() { + final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + assertEquals(Fatigue.ALERT, model.getFatigue()); + for (final Fatigue fatigue : Fatigue.values()) { + model.setFatigue(fatigue); + assertEquals(fatigue, model.getFatigue()); + assertEquals("The giant looks healthy, " + fatigue.toString() + " and saturated.", model.toString()); + } + } + + /** + * Verify if the nourishment level is set properly though the constructor and setter + */ + @Test + public void testSetNourishment() { + final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + assertEquals(Nourishment.SATURATED, model.getNourishment()); + for (final Nourishment nourishment : Nourishment.values()) { + model.setNourishment(nourishment); + assertEquals(nourishment, model.getNourishment()); + assertEquals("The giant looks healthy, alert and " + nourishment.toString() + ".", model.toString()); + } + } + +} diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java new file mode 100644 index 000000000..8d7a7dfbf --- /dev/null +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java @@ -0,0 +1,64 @@ +package com.iluwatar.model.view.controller; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +/** + * Date: 12/20/15 - 2:04 PM + * + * @author Jeroen Meulemeester + */ +public class GiantViewTest { + + /** + * The mocked standard out {@link PrintStream}, required since the actions of the views don't have + * any influence on any other accessible objects, except for writing to std-out using {@link + * System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * Verify if the {@link GiantView} does what it has to do: Print the {@link GiantModel} to the + * standard out stream, nothing more, nothing less. + */ + @Test + public void testDisplayGiant() { + final GiantView view = new GiantView(); + + final GiantModel model = mock(GiantModel.class); + view.displayGiant(model); + + verify(this.stdOutMock).println(model); + verifyNoMoreInteractions(model, this.stdOutMock); + + } + +} \ No newline at end of file From 6fe01e73b2b32c5c92a696e2e466c77a2a67eed4 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Mon, 21 Dec 2015 12:17:20 +0100 Subject: [PATCH 020/106] Add additional tests for model-view-presenter pattern --- .../model/view/presenter/AppTest.java | 18 ++++++++++++++ .../model/view/presenter/FileLoaderTest.java | 24 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java create mode 100644 model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java new file mode 100644 index 000000000..9b4aabc4d --- /dev/null +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java @@ -0,0 +1,18 @@ +package com.iluwatar.model.view.presenter; + +import org.junit.Test; + +/** + * + * Application test + * + */ +public class AppTest { + + @Test + public void test() { + String[] args = {}; + App.main(args); + } + +} diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java new file mode 100644 index 000000000..7fa4a9186 --- /dev/null +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java @@ -0,0 +1,24 @@ +package com.iluwatar.model.view.presenter; + +import org.junit.Test; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import static org.junit.Assert.*; + +/** + * Date: 12/21/15 - 12:12 PM + * + * @author Jeroen Meulemeester + */ +public class FileLoaderTest { + + @Test + public void testLoadData() throws Exception { + final FileLoader fileLoader = new FileLoader(); + fileLoader.setFileName("non-existing-file"); + assertNull(fileLoader.loadData()); + } + +} \ No newline at end of file From 531158c83610d2ffb6fb4655189212a2122a7e95 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Mon, 21 Dec 2015 13:29:25 +0100 Subject: [PATCH 021/106] Added tests for monostate pattern --- monostate/pom.xml | 5 ++ .../main/java/com/iluwatar/monostate/App.java | 4 +- .../com/iluwatar/monostate/LoadBalancer.java | 2 +- .../java/com/iluwatar/monostate/Server.java | 2 +- .../java/com/iluwatar/monostate/AppTest.java | 11 ----- .../iluwatar/monostate/LoadBalancerTest.java | 49 +++++++++++++++++++ 6 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java diff --git a/monostate/pom.xml b/monostate/pom.xml index 2f253084d..72e2231f1 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/monostate/src/main/java/com/iluwatar/monostate/App.java b/monostate/src/main/java/com/iluwatar/monostate/App.java index 0daad5b67..5c61371fa 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/App.java +++ b/monostate/src/main/java/com/iluwatar/monostate/App.java @@ -28,8 +28,8 @@ public class App { public static void main(String[] args) { LoadBalancer loadBalancer1 = new LoadBalancer(); LoadBalancer loadBalancer2 = new LoadBalancer(); - loadBalancer1.serverequest(new Request("Hello")); - loadBalancer2.serverequest(new Request("Hello World")); + loadBalancer1.serverRequest(new Request("Hello")); + loadBalancer2.serverRequest(new Request("Hello World")); } } diff --git a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java index b81e44251..5870ca0a7 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java +++ b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java @@ -39,7 +39,7 @@ public class LoadBalancer { return lastServedId; } - public void serverequest(Request request) { + public void serverRequest(Request request) { if (lastServedId >= servers.size()) { lastServedId = 0; } diff --git a/monostate/src/main/java/com/iluwatar/monostate/Server.java b/monostate/src/main/java/com/iluwatar/monostate/Server.java index f48f4ad0f..e0b3f850a 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/Server.java +++ b/monostate/src/main/java/com/iluwatar/monostate/Server.java @@ -25,7 +25,7 @@ public class Server { return port; } - public final void serve(Request request) { + public void serve(Request request) { System.out.println("Server ID " + id + " associated to host : " + getHost() + " and Port " + getPort() + " Processed request with value " + request.value); } diff --git a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java index c502dd14a..e216ae242 100644 --- a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java +++ b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java @@ -5,17 +5,6 @@ import org.junit.Test; public class AppTest { - @Test - public void testSameStateAmonstAllInstances() { - LoadBalancer balancer = new LoadBalancer(); - LoadBalancer balancer2 = new LoadBalancer(); - balancer.addServer(new Server("localhost", 8085, 6)); - // Both should have the same number of servers. - Assert.assertTrue(balancer.getNoOfServers() == balancer2.getNoOfServers()); - // Both Should have the same LastServedId - Assert.assertTrue(balancer.getLastServedId() == balancer2.getLastServedId()); - } - @Test public void testMain() { String[] args = {}; diff --git a/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java new file mode 100644 index 000000000..130adae14 --- /dev/null +++ b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java @@ -0,0 +1,49 @@ +package com.iluwatar.monostate; + +import org.junit.Assert; +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/21/15 - 12:26 PM + * + * @author Jeroen Meulemeester + */ +public class LoadBalancerTest { + + @Test + public void testSameStateAmongstAllInstances() { + final LoadBalancer firstBalancer = new LoadBalancer(); + final LoadBalancer secondBalancer = new LoadBalancer(); + firstBalancer.addServer(new Server("localhost", 8085, 6)); + // Both should have the same number of servers. + Assert.assertTrue(firstBalancer.getNoOfServers() == secondBalancer.getNoOfServers()); + // Both Should have the same LastServedId + Assert.assertTrue(firstBalancer.getLastServedId() == secondBalancer.getLastServedId()); + } + + @Test + public void testServe() { + final Server server = mock(Server.class); + + final LoadBalancer loadBalancer = new LoadBalancer(); + loadBalancer.addServer(server); + + verifyZeroInteractions(server); + + final Request request = new Request("test"); + for (int i = 0; i < loadBalancer.getNoOfServers() * 2; i++) { + loadBalancer.serverRequest(request); + } + + verify(server, times(2)).serve(request); + verifyNoMoreInteractions(server); + + } + +} From e3e0e32e92b97590088a9f47a88b222c1b5a384e Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Mon, 21 Dec 2015 14:35:36 +0100 Subject: [PATCH 022/106] Fixed failing unit test LoadBalancer has several static fields, this could cause problems since JUnit tests are executed concurrently. --- monostate/src/test/java/com/iluwatar/monostate/AppTest.java | 1 - .../test/java/com/iluwatar/monostate/LoadBalancerTest.java | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java index e216ae242..72341e3ff 100644 --- a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java +++ b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java @@ -9,7 +9,6 @@ public class AppTest { public void testMain() { String[] args = {}; App.main(args); - Assert.assertTrue(LoadBalancer.getLastServedId() == 2); } } diff --git a/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java index 130adae14..816443fbc 100644 --- a/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java +++ b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java @@ -3,11 +3,14 @@ package com.iluwatar.monostate; import org.junit.Assert; import org.junit.Test; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; /** * Date: 12/21/15 - 12:26 PM @@ -30,6 +33,9 @@ public class LoadBalancerTest { @Test public void testServe() { final Server server = mock(Server.class); + when(server.getHost()).thenReturn("testhost"); + when(server.getPort()).thenReturn(1234); + doNothing().when(server).serve(any(Request.class)); final LoadBalancer loadBalancer = new LoadBalancer(); loadBalancer.addServer(server); From 6e496e7c8682f15b0181c95d84b7054952ac4b2c Mon Sep 17 00:00:00 2001 From: Kirill Vlasov Date: Tue, 22 Dec 2015 14:48:24 +0500 Subject: [PATCH 023/106] Fixing squid:S1854 - Dead stores should be removed --- .../src/main/java/com/iluwatar/caching/App.java | 14 +++++++------- .../tolerantreader/RainbowFishSerializer.java | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/caching/src/main/java/com/iluwatar/caching/App.java b/caching/src/main/java/com/iluwatar/caching/App.java index c7f55db70..0d674f1ca 100644 --- a/caching/src/main/java/com/iluwatar/caching/App.java +++ b/caching/src/main/java/com/iluwatar/caching/App.java @@ -65,8 +65,8 @@ public class App { AppManager.save(userAccount1); System.out.println(AppManager.printCacheContent()); - userAccount1 = AppManager.find("001"); - userAccount1 = AppManager.find("001"); + AppManager.find("001"); + AppManager.find("001"); } /** @@ -80,15 +80,15 @@ public class App { AppManager.save(userAccount2); System.out.println(AppManager.printCacheContent()); - userAccount2 = AppManager.find("002"); + AppManager.find("002"); System.out.println(AppManager.printCacheContent()); userAccount2 = AppManager.find("002"); userAccount2.setUserName("Jane G."); AppManager.save(userAccount2); System.out.println(AppManager.printCacheContent()); - userAccount2 = AppManager.find("002"); + AppManager.find("002"); System.out.println(AppManager.printCacheContent()); - userAccount2 = AppManager.find("002"); + AppManager.find("002"); } /** @@ -106,12 +106,12 @@ public class App { AppManager.save(userAccount4); AppManager.save(userAccount5); System.out.println(AppManager.printCacheContent()); - userAccount3 = AppManager.find("003"); + AppManager.find("003"); System.out.println(AppManager.printCacheContent()); UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child."); AppManager.save(userAccount6); System.out.println(AppManager.printCacheContent()); - userAccount4 = AppManager.find("004"); + AppManager.find("004"); System.out.println(AppManager.printCacheContent()); } } diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java index 3929e06e7..8c4aa9e8f 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java @@ -70,10 +70,9 @@ public class RainbowFishSerializer { * @throws ClassNotFoundException */ public static RainbowFish readV1(String filename) throws IOException, ClassNotFoundException { - Map map = null; FileInputStream fileIn = new FileInputStream(filename); ObjectInputStream objIn = new ObjectInputStream(fileIn); - map = (Map) objIn.readObject(); + Map map = (Map) objIn.readObject(); objIn.close(); fileIn.close(); return new RainbowFish(map.get("name"), Integer.parseInt(map.get("age")), Integer.parseInt(map From 9fbb085985e092fc5d7f631e154b66d2ade7a15b Mon Sep 17 00:00:00 2001 From: Ilkka Seppala Date: Wed, 23 Dec 2015 13:20:39 +0200 Subject: [PATCH 024/106] Checkstyle fails the build when violations are detected --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9fa150dd4..724b058f1 100644 --- a/pom.xml +++ b/pom.xml @@ -255,8 +255,8 @@ checkstyle.xml UTF-8 - false - false + true + true From cec9a99410a0544ff0f1a5853443ef9dcff0a9e7 Mon Sep 17 00:00:00 2001 From: Ilkka Seppala Date: Fri, 25 Dec 2015 23:49:28 +0200 Subject: [PATCH 025/106] Adjust checkstyle rules. Make checkstyle fail the build when violations are found. Correct all current checkstyle violations. --- .../com/iluwatar/abstractfactory/App.java | 85 +++++---- .../iluwatar/async/method/invocation/App.java | 47 ++--- .../async/method/invocation/AsyncResult.java | 2 - .../invocation/ThreadAsyncExecutor.java | 24 +-- .../invocation/ThreadAsyncExecutorTest.java | 76 ++++---- .../main/java/com/iluwatar/builder/Hero.java | 3 + .../business/delegate/BusinessDelegate.java | 26 +-- .../main/java/com/iluwatar/caching/App.java | 4 +- .../java/com/iluwatar/caching/AppManager.java | 23 ++- .../java/com/iluwatar/caching/CacheStore.java | 89 +++++---- .../{DBManager.java => DbManager.java} | 53 ++++-- .../caching/{LRUCache.java => LruCache.java} | 65 ++++--- .../com/iluwatar/caching/UserAccount.java | 19 +- .../java/com/iluwatar/caching/AppTest.java | 2 +- .../main/java/com/iluwatar/callback/App.java | 3 + .../main/java/com/iluwatar/callback/Task.java | 3 + .../com/iluwatar/chain/RequestHandler.java | 3 + checkstyle.xml | 75 ++------ .../java/com/iluwatar/command/Target.java | 3 + .../java/com/iluwatar/command/Wizard.java | 9 + .../iluwatar/composite/LetterComposite.java | 3 + .../java/com/iluwatar/composite/Sentence.java | 3 + .../java/com/iluwatar/composite/Word.java | 3 + dao/src/main/java/com/iluwatar/dao/App.java | 12 +- .../main/java/com/iluwatar/dao/Customer.java | 6 +- dao/src/main/resources/log4j.xml | 20 +-- .../iluwatar/doublechecked/locking/App.java | 2 +- .../doublechecked/locking/Inventory.java | 6 + .../doublechecked/locking/InventoryTest.java | 4 +- .../java/com/iluwatar/doubledispatch/App.java | 30 ++-- .../iluwatar/doubledispatch/Rectangle.java | 3 + .../doubledispatch/CollisionTest.java | 12 +- .../event/aggregator/EventEmitterTest.java | 62 +++---- .../event/aggregator/KingsHandTest.java | 2 +- .../java/com/iluwatar/execute/around/App.java | 3 - .../execute/around/SimpleFileWriter.java | 3 + .../execute/around/SimpleFileWriterTest.java | 6 +- .../facade/DwarvenGoldmineFacade.java | 3 + .../iluwatar/facade/DwarvenMineWorker.java | 3 + .../com/iluwatar/fluentinterface/app/App.java | 19 +- .../lazy/DecoratingIterator.java | 4 - .../simple/SimpleFluentIterable.java | 10 +- .../fluentiterable/FluentIterableTest.java | 2 +- .../iluwatar/flux/dispatcher/Dispatcher.java | 3 + .../com/iluwatar/flyweight/AlchemistShop.java | 6 + .../com/iluwatar/front/controller/App.java | 40 +++-- .../controller/ApplicationException.java | 8 +- .../front/controller/ArcherCommand.java | 8 +- .../iluwatar/front/controller/ArcherView.java | 8 +- .../front/controller/CatapultCommand.java | 8 +- .../front/controller/CatapultView.java | 8 +- .../iluwatar/front/controller/Command.java | 4 +- .../iluwatar/front/controller/ErrorView.java | 8 +- .../front/controller/FrontController.java | 52 +++--- .../front/controller/UnknownCommand.java | 8 +- .../com/iluwatar/front/controller/View.java | 2 +- .../iluwatar/front/controller/AppTest.java | 12 +- .../controller/ApplicationExceptionTest.java | 4 +- .../com/iluwatar/halfsynchalfasync/App.java | 15 +- .../intercepting/filter/AddressFilter.java | 3 +- .../iluwatar/intercepting/filter/Client.java | 6 +- .../iluwatar/intercepting/filter/Filter.java | 9 - .../intercepting/filter/FilterChain.java | 9 + .../iluwatar/intercepting/filter/Order.java | 3 + .../iluwatar/intercepting/filter/Target.java | 6 +- .../intercepting/filter/FilterTest.java | 3 + .../java/com/iluwatar/interpreter/App.java | 6 +- .../iluwatar/interpreter/ExpressionTest.java | 6 +- .../main/java/com/iluwatar/iterator/App.java | 8 +- .../com/iluwatar/iterator/TreasureChest.java | 10 +- .../iterator/TreasureChestItemIterator.java | 3 + .../iluwatar/iterator/TreasureChestTest.java | 2 +- .../main/java/com/iluwatar/layers/App.java | 42 +++-- .../iluwatar/layers/CakeBakingService.java | 13 -- .../java/com/iluwatar/layers/CakeInfo.java | 9 + .../com/iluwatar/layers/CakeLayerInfo.java | 6 + .../com/iluwatar/layers/CakeToppingInfo.java | 6 + .../main/resources/META-INF/persistence.xml | 6 +- .../src/main/resources/applicationContext.xml | 67 ++++--- .../java/com/iluwatar/lazy/loading/Heavy.java | 3 + .../iluwatar/lazy/loading/HolderNaive.java | 6 + .../lazy/loading/HolderThreadSafe.java | 6 + .../iluwatar/lazy/loading/Java8Holder.java | 2 +- .../main/java/com/iluwatar/memento/App.java | 3 + .../main/java/com/iluwatar/memento/Star.java | 6 + .../com/iluwatar/message/channel/App.java | 3 - .../model/view/presenter/FileLoader.java | 4 +- .../view/presenter/FileSelectorJFrame.java | 16 +- .../view/presenter/FileSelectorPresenter.java | 7 +- .../presenter/FileSelectorPresenterTest.java | 15 +- .../com/iluwatar/monostate/LoadBalancer.java | 6 + .../java/com/iluwatar/monostate/Server.java | 3 + .../dom/app/homepage/HomePageService.java | 4 +- .../dom/modules/simple/SimpleObjects.java | 5 +- .../modules/simple/SimpleObjectCreate.java | 2 - .../scenarios/RecreateSimpleObjects.java | 8 +- .../bootstrap/SimpleAppSystemInitializer.java | 3 + .../modules/simple/SimpleObjectGlue.java | 4 +- .../integtests/tests/SimpleAppIntegTest.java | 14 +- .../modules/simple/SimpleObjectIntegTest.java | 153 ++++++++-------- .../simple/SimpleObjectsIntegTest.java | 170 +++++++++--------- .../domainapp/webapp/SimpleApplication.java | 3 +- .../com/iluwatar/nullobject/NodeImpl.java | 3 + .../com/iluwatar/object/pool/ObjectPool.java | 5 +- .../com/iluwatar/object/pool/Oliphaunt.java | 3 + .../java/com/iluwatar/observer/Weather.java | 3 + .../iluwatar/observer/generic/GWeather.java | 3 + .../iluwatar/observer/generic/Observable.java | 3 + .../iluwatar/observer/generic/Observer.java | 4 - .../com/iluwatar/poison/pill/Consumer.java | 7 +- .../iluwatar/poison/pill/MessageQueue.java | 2 +- ...QPublishPoint.java => MqPublishPoint.java} | 2 +- ...scribePoint.java => MqSubscribePoint.java} | 2 +- .../com/iluwatar/poison/pill/Producer.java | 13 +- pom.xml | 2 +- .../privateclassdata/ImmutableStew.java | 3 + .../com/iluwatar/privateclassdata/Stew.java | 9 + .../iluwatar/privateclassdata/StewData.java | 3 + .../com/iluwatar/producer/consumer/App.java | 17 +- .../iluwatar/producer/consumer/Consumer.java | 3 + .../iluwatar/producer/consumer/Producer.java | 3 + .../java/com/iluwatar/property/Character.java | 6 + .../iluwatar/prototype/HeroFactoryImpl.java | 12 ++ .../src/main/java/com/iluwatar/proxy/App.java | 3 + .../com/iluwatar/publish/subscribe/App.java | 4 - .../java/com/iluwatar/reactor/app/App.java | 2 - .../com/iluwatar/reactor/app/AppClient.java | 16 +- .../reactor/framework/AbstractNioChannel.java | 1 + .../reactor/framework/NioReactor.java | 81 +++++---- .../com/iluwatar/repository/AppConfig.java | 7 +- .../java/com/iluwatar/repository/Person.java | 33 ++-- .../repository/PersonSpecifications.java | 7 + .../main/resources/META-INF/persistence.xml | 6 +- .../src/main/resources/applicationContext.xml | 66 ++++--- .../AnnotationBasedRepositoryTest.java | 4 +- .../iluwatar/repository/AppConfigTest.java | 5 +- .../iluwatar/repository/RepositoryTest.java | 4 +- .../acquisition/is/initialization/App.java | 3 - .../main/java/com/iluwatar/servant/App.java | 14 +- .../main/java/com/iluwatar/servant/King.java | 6 +- .../main/java/com/iluwatar/servant/Queen.java | 3 +- .../java/com/iluwatar/servant/Servant.java | 14 +- .../com/iluwatar/servicelayer/app/App.java | 6 + .../servicelayer/common/DaoBaseImpl.java | 15 +- .../servicelayer/hibernate/HibernateUtil.java | 6 +- .../servicelayer/magic/MagicServiceImpl.java | 3 + .../servicelayer/spell/SpellDaoImpl.java | 3 +- .../spellbook/SpellbookDaoImpl.java | 3 +- .../servicelayer/wizard/WizardDaoImpl.java | 3 +- .../iluwatar/servicelocator/ServiceImpl.java | 3 + .../com/iluwatar/singleton/IvoryTower.java | 4 +- .../ThreadSafeDoubleCheckLocking.java | 10 +- .../ThreadSafeLazyLoadedIvoryTower.java | 2 +- .../LazyLoadedSingletonThreadSafetyTest.java | 20 ++- .../com/iluwatar/specification/app/App.java | 3 + .../creature/AbstractCreature.java | 3 + .../src/main/java/com/iluwatar/state/App.java | 3 + .../main/java/com/iluwatar/state/Mammoth.java | 3 + .../java/com/iluwatar/stepbuilder/App.java | 2 +- .../templatemethod/StealingMethod.java | 3 + .../java/com/iluwatar/tolerantreader/App.java | 3 + .../iluwatar/tolerantreader/RainbowFish.java | 3 + .../tolerantreader/RainbowFishSerializer.java | 13 -- .../tolerantreader/RainbowFishV2.java | 3 + .../java/com/iluwatar/twin/BallThread.java | 3 + .../main/java/com/iluwatar/twin/GameItem.java | 3 - .../main/java/com/iluwatar/visitor/Unit.java | 3 + 167 files changed, 1242 insertions(+), 969 deletions(-) rename caching/src/main/java/com/iluwatar/caching/{DBManager.java => DbManager.java} (73%) rename caching/src/main/java/com/iluwatar/caching/{LRUCache.java => LruCache.java} (70%) rename poison-pill/src/main/java/com/iluwatar/poison/pill/{MQPublishPoint.java => MqPublishPoint.java} (81%) rename poison-pill/src/main/java/com/iluwatar/poison/pill/{MQSubscribePoint.java => MqSubscribePoint.java} (80%) diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java index 9a32a091a..cdde3bd8f 100644 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java +++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java @@ -1,20 +1,18 @@ package com.iluwatar.abstractfactory; - /** * - * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that - * have a common theme without specifying their concrete classes. In normal usage, the client - * software creates a concrete implementation of the abstract factory and then uses the generic - * interface of the factory to create the concrete objects that are part of the theme. The client - * does not know (or care) which concrete objects it gets from each of these internal factories, - * since it uses only the generic interfaces of their products. This pattern separates the details - * of implementation of a set of objects from their general usage and relies on object composition, - * as object creation is implemented in methods exposed in the factory interface. + * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme + * without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of + * the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part + * of the theme. The client does not know (or care) which concrete objects it gets from each of these internal + * factories, since it uses only the generic interfaces of their products. This pattern separates the details of + * implementation of a set of objects from their general usage and relies on object composition, as object creation is + * implemented in methods exposed in the factory interface. *

- * The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) and - * its implementations ({@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses both - * concrete implementations to create a king, a castle and an army. + * The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) and its implementations ( + * {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses both concrete implementations to create a + * king, a castle and an army. * */ public class App { @@ -23,11 +21,8 @@ public class App { private Castle castle; private Army army; - /** * Creates kingdom - * - * @param factory */ public void createKingdom(final KingdomFactory factory) { setKing(factory.createKing()); @@ -47,14 +42,6 @@ public class App { return factory.createKing(); } - Castle getCastle(final KingdomFactory factory) { - return factory.createCastle(); - } - - Army getArmy(final KingdomFactory factory) { - return factory.createArmy(); - } - public King getKing() { return king; } @@ -62,6 +49,10 @@ public class App { private void setKing(final King king) { this.king = king; } + + Castle getCastle(final KingdomFactory factory) { + return factory.createCastle(); + } public Castle getCastle() { return castle; @@ -70,6 +61,10 @@ public class App { private void setCastle(final Castle castle) { this.castle = castle; } + + Army getArmy(final KingdomFactory factory) { + return factory.createArmy(); + } public Army getArmy() { return army; @@ -79,32 +74,32 @@ public class App { this.army = army; } - /** * Program entry point * - * @param args command line args + * @param args + * command line args */ public static void main(String[] args) { - - App app = new App(); - - System.out.println("Elf Kingdom"); - KingdomFactory elfKingdomFactory; - elfKingdomFactory = app.getElfKingdomFactory(); - app.createKingdom(elfKingdomFactory); - System.out.println(app.getArmy().getDescription()); - System.out.println(app.getCastle().getDescription()); - System.out.println(app.getKing().getDescription()); - - System.out.println("\nOrc Kingdom"); - KingdomFactory orcKingdomFactory; - orcKingdomFactory = app.getOrcKingdomFactory(); - app.createKingdom(orcKingdomFactory); - System.out.println(app.getArmy().getDescription()); - System.out.println(app.getCastle().getDescription()); - System.out.println(app.getKing().getDescription()); - + + App app = new App(); + + System.out.println("Elf Kingdom"); + KingdomFactory elfKingdomFactory; + elfKingdomFactory = app.getElfKingdomFactory(); + app.createKingdom(elfKingdomFactory); + System.out.println(app.getArmy().getDescription()); + System.out.println(app.getCastle().getDescription()); + System.out.println(app.getKing().getDescription()); + + System.out.println("\nOrc Kingdom"); + KingdomFactory orcKingdomFactory; + orcKingdomFactory = app.getOrcKingdomFactory(); + app.createKingdom(orcKingdomFactory); + System.out.println(app.getArmy().getDescription()); + System.out.println(app.getCastle().getDescription()); + System.out.println(app.getKing().getDescription()); + } - + } diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java index 0b8ee3649..6f2d4a8fc 100644 --- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java +++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/App.java @@ -4,24 +4,23 @@ import java.util.concurrent.Callable; /** * This application demonstrates the async method invocation pattern. Key parts of the pattern are - * AsyncResult which is an intermediate container for an asynchronously evaluated - * value, AsyncCallback which can be provided to be executed on task completion and - * AsyncExecutor that manages the execution of the async tasks. + * AsyncResult which is an intermediate container for an asynchronously evaluated value, + * AsyncCallback which can be provided to be executed on task completion and AsyncExecutor + * that manages the execution of the async tasks. *

- * The main method shows example flow of async invocations. The main thread starts multiple tasks - * with variable durations and then continues its own work. When the main thread has done it's job - * it collects the results of the async tasks. Two of the tasks are handled with callbacks, meaning - * the callbacks are executed immediately when the tasks complete. + * The main method shows example flow of async invocations. The main thread starts multiple tasks with variable + * durations and then continues its own work. When the main thread has done it's job it collects the results of the + * async tasks. Two of the tasks are handled with callbacks, meaning the callbacks are executed immediately when the + * tasks complete. *

- * Noteworthy difference of thread usage between the async results and callbacks is that the async - * results are collected in the main thread but the callbacks are executed within the worker - * threads. This should be noted when working with thread pools. + * Noteworthy difference of thread usage between the async results and callbacks is that the async results are collected + * in the main thread but the callbacks are executed within the worker threads. This should be noted when working with + * thread pools. *

- * Java provides its own implementations of async method invocation pattern. FutureTask, - * CompletableFuture and ExecutorService are the real world implementations of this pattern. But due - * to the nature of parallel programming, the implementations are not trivial. This example does not - * take all possible scenarios into account but rather provides a simple version that helps to - * understand the pattern. + * Java provides its own implementations of async method invocation pattern. FutureTask, CompletableFuture and + * ExecutorService are the real world implementations of this pattern. But due to the nature of parallel programming, + * the implementations are not trivial. This example does not take all possible scenarios into account but rather + * provides a simple version that helps to understand the pattern. * * @see AsyncResult * @see AsyncCallback @@ -33,6 +32,9 @@ import java.util.concurrent.Callable; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) throws Exception { // construct a new executor that will run async tasks AsyncExecutor executor = new ThreadAsyncExecutor(); @@ -41,10 +43,8 @@ public class App { AsyncResult asyncResult1 = executor.startProcess(lazyval(10, 500)); AsyncResult asyncResult2 = executor.startProcess(lazyval("test", 300)); AsyncResult asyncResult3 = executor.startProcess(lazyval(50L, 700)); - AsyncResult asyncResult4 = - executor.startProcess(lazyval(20, 400), callback("Callback result 4")); - AsyncResult asyncResult5 = - executor.startProcess(lazyval("callback", 600), callback("Callback result 5")); + AsyncResult asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Callback result 4")); + AsyncResult asyncResult5 = executor.startProcess(lazyval("callback", 600), callback("Callback result 5")); // emulate processing in the current thread while async tasks are running in their own threads Thread.sleep(350); // Oh boy I'm working hard here @@ -66,8 +66,10 @@ public class App { /** * Creates a callable that lazily evaluates to given value with artificial delay. * - * @param value value to evaluate - * @param delayMillis artificial delay in milliseconds + * @param value + * value to evaluate + * @param delayMillis + * artificial delay in milliseconds * @return new callable for lazy evaluation */ private static Callable lazyval(T value, long delayMillis) { @@ -81,7 +83,8 @@ public class App { /** * Creates a simple callback that logs the complete status of the async result. * - * @param name callback name + * @param name + * callback name * @return new async callback */ private static AsyncCallback callback(String name) { diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java index 6d77df8ec..d64180dad 100644 --- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java +++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/AsyncResult.java @@ -5,8 +5,6 @@ import java.util.concurrent.ExecutionException; /** * * AsyncResult interface - * - * @param */ public interface AsyncResult { diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java index 300934562..e935f9626 100644 --- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java +++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java @@ -29,13 +29,12 @@ public class ThreadAsyncExecutor implements AsyncExecutor { } catch (Exception ex) { result.setException(ex); } - }, "executor-" + idx.incrementAndGet()).start(); + } , "executor-" + idx.incrementAndGet()).start(); return result; } @Override - public T endProcess(AsyncResult asyncResult) throws ExecutionException, - InterruptedException { + public T endProcess(AsyncResult asyncResult) throws ExecutionException, InterruptedException { if (asyncResult.isCompleted()) { return asyncResult.getValue(); } else { @@ -45,9 +44,8 @@ public class ThreadAsyncExecutor implements AsyncExecutor { } /** - * Simple implementation of async result that allows completing it successfully with a value or - * exceptionally with an exception. A really simplified version from its real life cousins - * FutureTask and CompletableFuture. + * Simple implementation of async result that allows completing it successfully with a value or exceptionally with an + * exception. A really simplified version from its real life cousins FutureTask and CompletableFuture. * * @see java.util.concurrent.FutureTask * @see java.util.concurrent.CompletableFuture @@ -71,10 +69,11 @@ public class ThreadAsyncExecutor implements AsyncExecutor { } /** - * Sets the value from successful execution and executes callback if available. Notifies any - * thread waiting for completion. + * Sets the value from successful execution and executes callback if available. Notifies any thread waiting for + * completion. * - * @param value value of the evaluated task + * @param value + * value of the evaluated task */ void setValue(T value) { this.value = value; @@ -86,10 +85,11 @@ public class ThreadAsyncExecutor implements AsyncExecutor { } /** - * Sets the exception from failed execution and executes callback if available. Notifies any - * thread waiting for completion. + * Sets the exception from failed execution and executes callback if available. Notifies any thread waiting for + * completion. * - * @param exception exception of the failed task + * @param exception + * exception of the failed task */ void setException(Exception exception) { this.exception = exception; diff --git a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java index 440e47552..f5727b1e8 100644 --- a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java +++ b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutorTest.java @@ -55,8 +55,7 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the happy path of - * {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} + * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} */ @Test(timeout = 3000) public void testSuccessfulTaskWithCallback() throws Exception { @@ -77,8 +76,7 @@ public class ThreadAsyncExecutorTest { verify(task, times(1)).call(); // ... same for the callback, we expect our object - final ArgumentCaptor> optionalCaptor = ArgumentCaptor - .forClass((Class) Optional.class); + final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class); verify(callback, times(1)).onComplete(eq(result), optionalCaptor.capture()); final Optional optionalException = optionalCaptor.getValue(); @@ -90,8 +88,8 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a - * task takes a while to execute + * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a task takes a while + * to execute */ @Test(timeout = 5000) public void testLongRunningTaskWithoutCallback() throws Exception { @@ -101,9 +99,9 @@ public class ThreadAsyncExecutorTest { final Object result = new Object(); final Callable task = mock(Callable.class); when(task.call()).thenAnswer(i -> { - Thread.sleep(1500); - return result; - }); + Thread.sleep(1500); + return result; + }); final AsyncResult asyncResult = executor.startProcess(task); assertNotNull(asyncResult); @@ -111,8 +109,7 @@ public class ThreadAsyncExecutorTest { try { asyncResult.getValue(); - fail( - "Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); + fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); } catch (IllegalStateException e) { assertNotNull(e.getMessage()); } @@ -130,9 +127,8 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the happy path of - * {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when a task takes a while to - * execute + * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when a task + * takes a while to execute */ @Test(timeout = 5000) public void testLongRunningTaskWithCallback() throws Exception { @@ -142,9 +138,9 @@ public class ThreadAsyncExecutorTest { final Object result = new Object(); final Callable task = mock(Callable.class); when(task.call()).thenAnswer(i -> { - Thread.sleep(1500); - return result; - }); + Thread.sleep(1500); + return result; + }); final AsyncCallback callback = mock(AsyncCallback.class); final AsyncResult asyncResult = executor.startProcess(task, callback); @@ -155,8 +151,7 @@ public class ThreadAsyncExecutorTest { try { asyncResult.getValue(); - fail( - "Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); + fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); } catch (IllegalStateException e) { assertNotNull(e.getMessage()); } @@ -164,8 +159,7 @@ public class ThreadAsyncExecutorTest { // Our task should only execute once, but it can take a while ... verify(task, timeout(3000).times(1)).call(); - final ArgumentCaptor> optionalCaptor = ArgumentCaptor - .forClass((Class) Optional.class); + final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class); verify(callback, timeout(3000).times(1)).onComplete(eq(result), optionalCaptor.capture()); final Optional optionalException = optionalCaptor.getValue(); @@ -182,9 +176,8 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a - * task takes a while to execute, while waiting on the result using - * {@link ThreadAsyncExecutor#endProcess(AsyncResult)} + * Test used to verify the happy path of {@link ThreadAsyncExecutor#startProcess(Callable)} when a task takes a while + * to execute, while waiting on the result using {@link ThreadAsyncExecutor#endProcess(AsyncResult)} */ @Test(timeout = 5000) public void testEndProcess() throws Exception { @@ -194,9 +187,9 @@ public class ThreadAsyncExecutorTest { final Object result = new Object(); final Callable task = mock(Callable.class); when(task.call()).thenAnswer(i -> { - Thread.sleep(1500); - return result; - }); + Thread.sleep(1500); + return result; + }); final AsyncResult asyncResult = executor.startProcess(task); assertNotNull(asyncResult); @@ -204,8 +197,7 @@ public class ThreadAsyncExecutorTest { try { asyncResult.getValue(); - fail( - "Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); + fail("Expected IllegalStateException when calling AsyncResult#getValue on a non-completed task"); } catch (IllegalStateException e) { assertNotNull(e.getMessage()); } @@ -220,8 +212,7 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable)} when - * the callable is 'null' + * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable)} when the callable is 'null' */ @Test(timeout = 3000) public void testNullTask() throws Exception { @@ -229,8 +220,7 @@ public class ThreadAsyncExecutorTest { final ThreadAsyncExecutor executor = new ThreadAsyncExecutor(); final AsyncResult asyncResult = executor.startProcess(null); - assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", - asyncResult); + assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", asyncResult); asyncResult.await(); // Prevent timing issues, and wait until the result is available assertTrue(asyncResult.isCompleted()); @@ -246,9 +236,8 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the behaviour of - * {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when the callable is 'null', - * but the asynchronous callback is provided + * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when the + * callable is 'null', but the asynchronous callback is provided */ @Test(timeout = 3000) public void testNullTaskWithCallback() throws Exception { @@ -257,13 +246,11 @@ public class ThreadAsyncExecutorTest { final AsyncCallback callback = mock(AsyncCallback.class); final AsyncResult asyncResult = executor.startProcess(null, callback); - assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", - asyncResult); + assertNotNull("The AsyncResult should not be 'null', even though the task was 'null'.", asyncResult); asyncResult.await(); // Prevent timing issues, and wait until the result is available assertTrue(asyncResult.isCompleted()); - final ArgumentCaptor> optionalCaptor = ArgumentCaptor - .forClass((Class) Optional.class); + final ArgumentCaptor> optionalCaptor = ArgumentCaptor.forClass((Class) Optional.class); verify(callback, times(1)).onComplete(Matchers.isNull(), optionalCaptor.capture()); final Optional optionalException = optionalCaptor.getValue(); @@ -286,9 +273,8 @@ public class ThreadAsyncExecutorTest { } /** - * Test used to verify the behaviour of - * {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when both the callable and - * the asynchronous callback are 'null' + * Test used to verify the behaviour of {@link ThreadAsyncExecutor#startProcess(Callable, AsyncCallback)} when both + * the callable and the asynchronous callback are 'null' */ @Test(timeout = 3000) public void testNullTaskWithNullCallback() throws Exception { @@ -296,9 +282,7 @@ public class ThreadAsyncExecutorTest { final ThreadAsyncExecutor executor = new ThreadAsyncExecutor(); final AsyncResult asyncResult = executor.startProcess(null, null); - assertNotNull( - "The AsyncResult should not be 'null', even though the task and callback were 'null'.", - asyncResult); + assertNotNull("The AsyncResult should not be 'null', even though the task and callback were 'null'.", asyncResult); asyncResult.await(); // Prevent timing issues, and wait until the result is available assertTrue(asyncResult.isCompleted()); diff --git a/builder/src/main/java/com/iluwatar/builder/Hero.java b/builder/src/main/java/com/iluwatar/builder/Hero.java index 54be11ea3..cf7289d51 100644 --- a/builder/src/main/java/com/iluwatar/builder/Hero.java +++ b/builder/src/main/java/com/iluwatar/builder/Hero.java @@ -93,6 +93,9 @@ public class Hero { private Armor armor; private Weapon weapon; + /** + * Constructor + */ public HeroBuilder(Profession profession, String name) { if (profession == null || name == null) { throw new IllegalArgumentException("profession and name can not be null"); diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java index a3c9a00e7..7fb709bcf 100644 --- a/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java +++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java @@ -5,20 +5,20 @@ package com.iluwatar.business.delegate; */ public class BusinessDelegate { - private BusinessLookup lookupService; - private BusinessService businessService; - private ServiceType serviceType; + private BusinessLookup lookupService; + private BusinessService businessService; + private ServiceType serviceType; - public void setLookupService(BusinessLookup businessLookup) { - this.lookupService = businessLookup; - } + public void setLookupService(BusinessLookup businessLookup) { + this.lookupService = businessLookup; + } - public void setServiceType(ServiceType serviceType) { - this.serviceType = serviceType; - } + public void setServiceType(ServiceType serviceType) { + this.serviceType = serviceType; + } - public void doTask() { - businessService = lookupService.getBusinessService(serviceType); - businessService.doProcessing(); - } + public void doTask() { + businessService = lookupService.getBusinessService(serviceType); + businessService.doProcessing(); + } } diff --git a/caching/src/main/java/com/iluwatar/caching/App.java b/caching/src/main/java/com/iluwatar/caching/App.java index c7f55db70..8dcef95ce 100644 --- a/caching/src/main/java/com/iluwatar/caching/App.java +++ b/caching/src/main/java/com/iluwatar/caching/App.java @@ -21,7 +21,7 @@ package com.iluwatar.caching; * application data. The cache itself is implemented as an internal (Java) data structure. It adopts * a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The three * strategies are individually tested. The testing of the cache is restricted towards saving and - * querying of user accounts from the underlying data store ( {@link DBManager}). The main class ( + * querying of user accounts from the underlying data store ( {@link DbManager}). The main class ( * {@link App} is not aware of the underlying mechanics of the application (i.e. save and query) and * whether the data is coming from the cache or the DB (i.e. separation of concern). The AppManager * ({@link AppManager}) handles the transaction of data to-and-from the underlying data store @@ -43,7 +43,7 @@ public class App { * @param args command line args */ public static void main(String[] args) { - AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests + AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests // and the App class to avoid Maven compilation errors. Set flag to // true to run the tests with MongoDB (provided that MongoDB is // installed and socket connection is open). diff --git a/caching/src/main/java/com/iluwatar/caching/AppManager.java b/caching/src/main/java/com/iluwatar/caching/AppManager.java index 08132e327..925320cd6 100644 --- a/caching/src/main/java/com/iluwatar/caching/AppManager.java +++ b/caching/src/main/java/com/iluwatar/caching/AppManager.java @@ -21,18 +21,21 @@ public class AppManager { * data storage or a simple Java data structure to (temporarily) store the data/objects during * runtime. */ - public static void initDB(boolean useMongoDB) { - if (useMongoDB) { + public static void initDb(boolean useMongoDb) { + if (useMongoDb) { try { - DBManager.connect(); + DbManager.connect(); } catch (ParseException e) { e.printStackTrace(); } } else { - DBManager.createVirtualDB(); + DbManager.createVirtualDb(); } } + /** + * Initialize caching policy + */ public static void initCachingPolicy(CachingPolicy policy) { cachingPolicy = policy; if (cachingPolicy == CachingPolicy.BEHIND) { @@ -50,15 +53,21 @@ public class AppManager { CacheStore.initCapacity(capacity); } - public static UserAccount find(String userID) { + /** + * Find user account + */ + public static UserAccount find(String userId) { if (cachingPolicy == CachingPolicy.THROUGH || cachingPolicy == CachingPolicy.AROUND) { - return CacheStore.readThrough(userID); + return CacheStore.readThrough(userId); } else if (cachingPolicy == CachingPolicy.BEHIND) { - return CacheStore.readThroughWithWriteBackPolicy(userID); + return CacheStore.readThroughWithWriteBackPolicy(userId); } return null; } + /** + * Save user account + */ public static void save(UserAccount userAccount) { if (cachingPolicy == CachingPolicy.THROUGH) { CacheStore.writeThrough(userAccount); diff --git a/caching/src/main/java/com/iluwatar/caching/CacheStore.java b/caching/src/main/java/com/iluwatar/caching/CacheStore.java index 2041ac14f..95278c746 100644 --- a/caching/src/main/java/com/iluwatar/caching/CacheStore.java +++ b/caching/src/main/java/com/iluwatar/caching/CacheStore.java @@ -9,73 +9,96 @@ import java.util.ArrayList; */ public class CacheStore { - static LRUCache cache = null; + static LruCache cache = null; + /** + * Init cache capacity + */ public static void initCapacity(int capacity) { - if (null == cache) - cache = new LRUCache(capacity); - else + if (null == cache) { + cache = new LruCache(capacity); + } else { cache.setCapacity(capacity); + } } - public static UserAccount readThrough(String userID) { - if (cache.contains(userID)) { + /** + * Get user account using read-through cache + */ + public static UserAccount readThrough(String userId) { + if (cache.contains(userId)) { System.out.println("# Cache Hit!"); - return cache.get(userID); + return cache.get(userId); } System.out.println("# Cache Miss!"); - UserAccount userAccount = DBManager.readFromDB(userID); - cache.set(userID, userAccount); + UserAccount userAccount = DbManager.readFromDb(userId); + cache.set(userId, userAccount); return userAccount; } + /** + * Get user account using write-through cache + */ public static void writeThrough(UserAccount userAccount) { - if (cache.contains(userAccount.getUserID())) { - DBManager.updateDB(userAccount); + if (cache.contains(userAccount.getUserId())) { + DbManager.updateDb(userAccount); } else { - DBManager.writeToDB(userAccount); + DbManager.writeToDb(userAccount); } - cache.set(userAccount.getUserID(), userAccount); + cache.set(userAccount.getUserId(), userAccount); } + /** + * Get user account using write-around cache + */ public static void writeAround(UserAccount userAccount) { - if (cache.contains(userAccount.getUserID())) { - DBManager.updateDB(userAccount); - cache.invalidate(userAccount.getUserID()); // Cache data has been updated -- remove older + if (cache.contains(userAccount.getUserId())) { + DbManager.updateDb(userAccount); + cache.invalidate(userAccount.getUserId()); // Cache data has been updated -- remove older // version from cache. } else { - DBManager.writeToDB(userAccount); + DbManager.writeToDb(userAccount); } } - public static UserAccount readThroughWithWriteBackPolicy(String userID) { - if (cache.contains(userID)) { + /** + * Get user account using read-through cache with write-back policy + */ + public static UserAccount readThroughWithWriteBackPolicy(String userId) { + if (cache.contains(userId)) { System.out.println("# Cache Hit!"); - return cache.get(userID); + return cache.get(userId); } System.out.println("# Cache Miss!"); - UserAccount userAccount = DBManager.readFromDB(userID); + UserAccount userAccount = DbManager.readFromDb(userId); if (cache.isFull()) { System.out.println("# Cache is FULL! Writing LRU data to DB..."); - UserAccount toBeWrittenToDB = cache.getLRUData(); - DBManager.upsertDB(toBeWrittenToDB); + UserAccount toBeWrittenToDb = cache.getLruData(); + DbManager.upsertDb(toBeWrittenToDb); } - cache.set(userID, userAccount); + cache.set(userId, userAccount); return userAccount; } + /** + * Set user account + */ public static void writeBehind(UserAccount userAccount) { - if (cache.isFull() && !cache.contains(userAccount.getUserID())) { + if (cache.isFull() && !cache.contains(userAccount.getUserId())) { System.out.println("# Cache is FULL! Writing LRU data to DB..."); - UserAccount toBeWrittenToDB = cache.getLRUData(); - DBManager.upsertDB(toBeWrittenToDB); + UserAccount toBeWrittenToDb = cache.getLruData(); + DbManager.upsertDb(toBeWrittenToDb); } - cache.set(userAccount.getUserID(), userAccount); + cache.set(userAccount.getUserId(), userAccount); } + /** + * Clears cache + */ public static void clearCache() { - if (null != cache) + if (null != cache) { cache.clear(); + } } /** @@ -83,14 +106,18 @@ public class CacheStore { */ public static void flushCache() { System.out.println("# flushCache..."); - if (null == cache) + if (null == cache) { return; + } ArrayList listOfUserAccounts = cache.getCacheDataInListForm(); for (UserAccount userAccount : listOfUserAccounts) { - DBManager.upsertDB(userAccount); + DbManager.upsertDb(userAccount); } } + /** + * Print user accounts + */ public static String print() { ArrayList listOfUserAccounts = cache.getCacheDataInListForm(); StringBuilder sb = new StringBuilder(); diff --git a/caching/src/main/java/com/iluwatar/caching/DBManager.java b/caching/src/main/java/com/iluwatar/caching/DbManager.java similarity index 73% rename from caching/src/main/java/com/iluwatar/caching/DBManager.java rename to caching/src/main/java/com/iluwatar/caching/DbManager.java index 07a5daeac..499ad5c3c 100644 --- a/caching/src/main/java/com/iluwatar/caching/DBManager.java +++ b/caching/src/main/java/com/iluwatar/caching/DbManager.java @@ -21,7 +21,7 @@ import com.mongodb.client.model.UpdateOptions; * during runtime (createVirtualDB()).

* */ -public class DBManager { +public class DbManager { private static MongoClient mongoClient; private static MongoDatabase db; @@ -29,21 +29,31 @@ public class DBManager { private static HashMap virtualDB; - public static void createVirtualDB() { + /** + * Create DB + */ + public static void createVirtualDb() { useMongoDB = false; virtualDB = new HashMap(); } + /** + * Connect to DB + */ public static void connect() throws ParseException { useMongoDB = true; mongoClient = new MongoClient(); db = mongoClient.getDatabase("test"); } - public static UserAccount readFromDB(String userID) { + /** + * Read user account from DB + */ + public static UserAccount readFromDb(String userId) { if (!useMongoDB) { - if (virtualDB.containsKey(userID)) - return virtualDB.get(userID); + if (virtualDB.containsKey(userId)) { + return virtualDB.get(userId); + } return null; } if (null == db) { @@ -54,18 +64,22 @@ public class DBManager { } } FindIterable iterable = - db.getCollection("user_accounts").find(new Document("userID", userID)); - if (iterable == null) + db.getCollection("user_accounts").find(new Document("userID", userId)); + if (iterable == null) { return null; + } Document doc = iterable.first(); UserAccount userAccount = - new UserAccount(userID, doc.getString("userName"), doc.getString("additionalInfo")); + new UserAccount(userId, doc.getString("userName"), doc.getString("additionalInfo")); return userAccount; } - public static void writeToDB(UserAccount userAccount) { + /** + * Write user account to DB + */ + public static void writeToDb(UserAccount userAccount) { if (!useMongoDB) { - virtualDB.put(userAccount.getUserID(), userAccount); + virtualDB.put(userAccount.getUserId(), userAccount); return; } if (null == db) { @@ -76,13 +90,16 @@ public class DBManager { } } db.getCollection("user_accounts").insertOne( - new Document("userID", userAccount.getUserID()).append("userName", + new Document("userID", userAccount.getUserId()).append("userName", userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())); } - public static void updateDB(UserAccount userAccount) { + /** + * Update DB + */ + public static void updateDb(UserAccount userAccount) { if (!useMongoDB) { - virtualDB.put(userAccount.getUserID(), userAccount); + virtualDB.put(userAccount.getUserId(), userAccount); return; } if (null == db) { @@ -93,7 +110,7 @@ public class DBManager { } } db.getCollection("user_accounts").updateOne( - new Document("userID", userAccount.getUserID()), + new Document("userID", userAccount.getUserId()), new Document("$set", new Document("userName", userAccount.getUserName()).append( "additionalInfo", userAccount.getAdditionalInfo()))); } @@ -102,9 +119,9 @@ public class DBManager { * * Insert data into DB if it does not exist. Else, update it. */ - public static void upsertDB(UserAccount userAccount) { + public static void upsertDb(UserAccount userAccount) { if (!useMongoDB) { - virtualDB.put(userAccount.getUserID(), userAccount); + virtualDB.put(userAccount.getUserId(), userAccount); return; } if (null == db) { @@ -115,8 +132,8 @@ public class DBManager { } } db.getCollection("user_accounts").updateOne( - new Document("userID", userAccount.getUserID()), - new Document("$set", new Document("userID", userAccount.getUserID()).append("userName", + new Document("userID", userAccount.getUserId()), + new Document("$set", new Document("userID", userAccount.getUserId()).append("userName", userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())), new UpdateOptions().upsert(true)); } diff --git a/caching/src/main/java/com/iluwatar/caching/LRUCache.java b/caching/src/main/java/com/iluwatar/caching/LruCache.java similarity index 70% rename from caching/src/main/java/com/iluwatar/caching/LRUCache.java rename to caching/src/main/java/com/iluwatar/caching/LruCache.java index 872f97256..e20275a40 100644 --- a/caching/src/main/java/com/iluwatar/caching/LRUCache.java +++ b/caching/src/main/java/com/iluwatar/caching/LruCache.java @@ -12,16 +12,16 @@ import java.util.HashMap; * LRU data is always at the end of the list. * */ -public class LRUCache { +public class LruCache { class Node { - String userID; + String userId; UserAccount userAccount; Node previous; Node next; - public Node(String userID, UserAccount userAccount) { - this.userID = userID; + public Node(String userId, UserAccount userAccount) { + this.userId = userId; this.userAccount = userAccount; } } @@ -31,13 +31,16 @@ public class LRUCache { Node head = null; Node end = null; - public LRUCache(int capacity) { + public LruCache(int capacity) { this.capacity = capacity; } - public UserAccount get(String userID) { - if (cache.containsKey(userID)) { - Node node = cache.get(userID); + /** + * Get user account + */ + public UserAccount get(String userId) { + if (cache.containsKey(userId)) { + Node node = cache.get(userId); remove(node); setHead(node); return node.userAccount; @@ -69,52 +72,63 @@ public class LRUCache { public void setHead(Node node) { node.next = head; node.previous = null; - if (head != null) + if (head != null) { head.previous = node; + } head = node; - if (end == null) + if (end == null) { end = head; + } } - public void set(String userID, UserAccount userAccount) { - if (cache.containsKey(userID)) { - Node old = cache.get(userID); + /** + * Set user account + */ + public void set(String userId, UserAccount userAccount) { + if (cache.containsKey(userId)) { + Node old = cache.get(userId); old.userAccount = userAccount; remove(old); setHead(old); } else { - Node newNode = new Node(userID, userAccount); + Node newNode = new Node(userId, userAccount); if (cache.size() >= capacity) { - System.out.println("# Cache is FULL! Removing " + end.userID + " from cache..."); - cache.remove(end.userID); // remove LRU data from cache. + System.out.println("# Cache is FULL! Removing " + end.userId + " from cache..."); + cache.remove(end.userId); // remove LRU data from cache. remove(end); setHead(newNode); } else { setHead(newNode); } - cache.put(userID, newNode); + cache.put(userId, newNode); } } - public boolean contains(String userID) { - return cache.containsKey(userID); + public boolean contains(String userId) { + return cache.containsKey(userId); } - public void invalidate(String userID) { - System.out.println("# " + userID + " has been updated! Removing older version from cache..."); - Node toBeRemoved = cache.get(userID); + /** + * Invalidate cache for user + */ + public void invalidate(String userId) { + System.out.println("# " + userId + " has been updated! Removing older version from cache..."); + Node toBeRemoved = cache.get(userId); remove(toBeRemoved); - cache.remove(userID); + cache.remove(userId); } public boolean isFull() { return cache.size() >= capacity; } - public UserAccount getLRUData() { + public UserAccount getLruData() { return end.userAccount; } + /** + * Clear cache + */ public void clear() { head = null; end = null; @@ -135,6 +149,9 @@ public class LRUCache { return listOfCacheData; } + /** + * Set cache capacity + */ public void setCapacity(int newCapacity) { if (capacity > newCapacity) { clear(); // Behavior can be modified to accommodate for decrease in cache size. For now, we'll diff --git a/caching/src/main/java/com/iluwatar/caching/UserAccount.java b/caching/src/main/java/com/iluwatar/caching/UserAccount.java index eff0878ad..0e281c429 100644 --- a/caching/src/main/java/com/iluwatar/caching/UserAccount.java +++ b/caching/src/main/java/com/iluwatar/caching/UserAccount.java @@ -6,22 +6,25 @@ package com.iluwatar.caching; * */ public class UserAccount { - private String userID; + private String userId; private String userName; private String additionalInfo; - public UserAccount(String userID, String userName, String additionalInfo) { - this.userID = userID; + /** + * Constructor + */ + public UserAccount(String userId, String userName, String additionalInfo) { + this.userId = userId; this.userName = userName; this.additionalInfo = additionalInfo; } - public String getUserID() { - return userID; + public String getUserId() { + return userId; } - public void setUserID(String userID) { - this.userID = userID; + public void setUserId(String userId) { + this.userId = userId; } public String getUserName() { @@ -42,6 +45,6 @@ public class UserAccount { @Override public String toString() { - return userID + ", " + userName + ", " + additionalInfo; + return userId + ", " + userName + ", " + additionalInfo; } } diff --git a/caching/src/test/java/com/iluwatar/caching/AppTest.java b/caching/src/test/java/com/iluwatar/caching/AppTest.java index ce5cddf08..35917da1c 100644 --- a/caching/src/test/java/com/iluwatar/caching/AppTest.java +++ b/caching/src/test/java/com/iluwatar/caching/AppTest.java @@ -16,7 +16,7 @@ public class AppTest { */ @Before public void setUp() { - AppManager.initDB(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests + AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests // to avoid Maven compilation errors. Set flag to true to run the // tests with MongoDB (provided that MongoDB is installed and socket // connection is open). diff --git a/callback/src/main/java/com/iluwatar/callback/App.java b/callback/src/main/java/com/iluwatar/callback/App.java index 81cb16f73..bc8b08cf0 100644 --- a/callback/src/main/java/com/iluwatar/callback/App.java +++ b/callback/src/main/java/com/iluwatar/callback/App.java @@ -9,6 +9,9 @@ package com.iluwatar.callback; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { Task task = new SimpleTask(); Callback callback = new Callback() { diff --git a/callback/src/main/java/com/iluwatar/callback/Task.java b/callback/src/main/java/com/iluwatar/callback/Task.java index d3be6c7a0..83e2cd4df 100644 --- a/callback/src/main/java/com/iluwatar/callback/Task.java +++ b/callback/src/main/java/com/iluwatar/callback/Task.java @@ -7,6 +7,9 @@ package com.iluwatar.callback; */ public abstract class Task { + /** + * Execute with callback + */ public final void executeWith(Callback callback) { execute(); if (callback != null) { diff --git a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java index fd58b9ea8..12db1f51c 100644 --- a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java +++ b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java @@ -13,6 +13,9 @@ public abstract class RequestHandler { this.next = next; } + /** + * Request handler + */ public void handleRequest(Request req) { if (next != null) { next.handleRequest(req); diff --git a/checkstyle.xml b/checkstyle.xml index 0ff943d95..6d969afde 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -25,8 +25,10 @@ + + - + @@ -48,7 +50,7 @@ - + @@ -61,7 +63,7 @@ - + @@ -86,9 +88,6 @@ - - - @@ -97,42 +96,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - @@ -180,11 +148,6 @@ - - - - @@ -195,7 +158,7 @@ - + diff --git a/command/src/main/java/com/iluwatar/command/Target.java b/command/src/main/java/com/iluwatar/command/Target.java index e12f758ff..731fe4d1f 100644 --- a/command/src/main/java/com/iluwatar/command/Target.java +++ b/command/src/main/java/com/iluwatar/command/Target.java @@ -30,6 +30,9 @@ public abstract class Target { @Override public abstract String toString(); + /** + * Print status + */ public void printStatus() { System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(), getVisibility())); diff --git a/command/src/main/java/com/iluwatar/command/Wizard.java b/command/src/main/java/com/iluwatar/command/Wizard.java index edef8d3a9..fb6407c74 100644 --- a/command/src/main/java/com/iluwatar/command/Wizard.java +++ b/command/src/main/java/com/iluwatar/command/Wizard.java @@ -15,12 +15,18 @@ public class Wizard { public Wizard() {} + /** + * Cast spell + */ public void castSpell(Command command, Target target) { System.out.println(this + " casts " + command + " at " + target); command.execute(target); undoStack.offerLast(command); } + /** + * Undo last spell + */ public void undoLastSpell() { if (!undoStack.isEmpty()) { Command previousSpell = undoStack.pollLast(); @@ -30,6 +36,9 @@ public class Wizard { } } + /** + * Redo last spell + */ public void redoLastSpell() { if (!redoStack.isEmpty()) { Command previousSpell = redoStack.pollLast(); diff --git a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java index 1fdf4fdb6..39655fa37 100644 --- a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java +++ b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java @@ -24,6 +24,9 @@ public abstract class LetterComposite { protected abstract void printThisAfter(); + /** + * Print + */ public void print() { printThisBefore(); for (LetterComposite letter : children) { diff --git a/composite/src/main/java/com/iluwatar/composite/Sentence.java b/composite/src/main/java/com/iluwatar/composite/Sentence.java index e6c626ea2..03f0c6949 100644 --- a/composite/src/main/java/com/iluwatar/composite/Sentence.java +++ b/composite/src/main/java/com/iluwatar/composite/Sentence.java @@ -9,6 +9,9 @@ import java.util.List; */ public class Sentence extends LetterComposite { + /** + * Constructor + */ public Sentence(List words) { for (Word w : words) { this.add(w); diff --git a/composite/src/main/java/com/iluwatar/composite/Word.java b/composite/src/main/java/com/iluwatar/composite/Word.java index 3060b0a1b..98c5f0b0d 100644 --- a/composite/src/main/java/com/iluwatar/composite/Word.java +++ b/composite/src/main/java/com/iluwatar/composite/Word.java @@ -9,6 +9,9 @@ import java.util.List; */ public class Word extends LetterComposite { + /** + * Constructor + */ public Word(List letters) { for (Letter l : letters) { this.add(l); diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java index 2e115d8ce..a9351689d 100644 --- a/dao/src/main/java/com/iluwatar/dao/App.java +++ b/dao/src/main/java/com/iluwatar/dao/App.java @@ -21,7 +21,7 @@ import org.apache.log4j.Logger; */ public class App { - private static Logger LOGGER = Logger.getLogger(App.class); + private static Logger log = Logger.getLogger(App.class); /** * Program entry point. @@ -30,17 +30,17 @@ public class App { */ public static void main(final String[] args) { final CustomerDaoImpl customerDao = new CustomerDaoImpl(generateSampleCustomers()); - LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); - LOGGER.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2)); + log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); + log.info("customerDao.getCusterById(2): " + customerDao.getCustomerById(2)); final Customer customer = new Customer(4, "Dan", "Danson"); customerDao.addCustomer(customer); - LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); + log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); customer.setFirstName("Daniel"); customer.setLastName("Danielson"); customerDao.updateCustomer(customer); - LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); + log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); customerDao.deleteCustomer(customer); - LOGGER.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); + log.info("customerDao.getAllCustomers(): " + customerDao.getAllCustomers()); } /** diff --git a/dao/src/main/java/com/iluwatar/dao/Customer.java b/dao/src/main/java/com/iluwatar/dao/Customer.java index e6d7f7763..3d782016b 100644 --- a/dao/src/main/java/com/iluwatar/dao/Customer.java +++ b/dao/src/main/java/com/iluwatar/dao/Customer.java @@ -11,6 +11,9 @@ public class Customer { private String firstName; private String lastName; + /** + * Constructor + */ public Customer(final int id, final String firstName, final String lastName) { this.id = id; this.firstName = firstName; @@ -54,8 +57,9 @@ public class Customer { isEqual = true; } else if (o != null && (getClass() == o.getClass())) { final Customer customer = (Customer) o; - if (getId() == customer.getId()) + if (getId() == customer.getId()) { isEqual = true; + } } return isEqual; } diff --git a/dao/src/main/resources/log4j.xml b/dao/src/main/resources/log4j.xml index 136817f50..906e37170 100644 --- a/dao/src/main/resources/log4j.xml +++ b/dao/src/main/resources/log4j.xml @@ -1,17 +1,17 @@ + xmlns:log4j='http://jakarta.apache.org/log4j/'> - - - - - + + + + + - - - - + + + + \ No newline at end of file diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java index 0cc62c995..79bf6aefd 100644 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java +++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java @@ -28,7 +28,7 @@ public class App { ExecutorService executorService = Executors.newFixedThreadPool(3); for (int i = 0; i < 3; i++) { executorService.execute(() -> { - while (inventory.addItem(new Item())); + while (inventory.addItem(new Item())) {}; }); } diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java index 0a17ac13d..1011b78b4 100644 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java +++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java @@ -17,12 +17,18 @@ public class Inventory { private final List items; private final Lock lock; + /** + * Constructor + */ public Inventory(int inventorySize) { this.inventorySize = inventorySize; this.items = new ArrayList<>(inventorySize); this.lock = new ReentrantLock(); } + /** + * Add item + */ public boolean addItem(Item item) { if (items.size() < inventorySize) { lock.lock(); diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java index 1bc43263f..0b7b6dabc 100644 --- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java +++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java @@ -77,8 +77,8 @@ public class InventoryTest { final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); for (int i = 0; i < THREAD_COUNT; i++) { executorService.execute(() -> { - while (inventory.addItem(new Item())) ; - }); + while (inventory.addItem(new Item())) {}; + }); } // Wait until all threads have finished diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java index 6514feb7f..98e19b770 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java @@ -5,22 +5,20 @@ import java.util.List; /** * - * When a message with a parameter is sent to an object, the resultant behaviour is defined by the - * implementation of that method in the receiver. Sometimes the behaviour must also be determined by - * the type of the parameter. + * When a message with a parameter is sent to an object, the resultant behaviour is defined by the implementation of + * that method in the receiver. Sometimes the behaviour must also be determined by the type of the parameter. *

- * One way to implement this would be to create multiple instanceof-checks for the methods - * parameter. However, this creates a maintenance issue. When new types are added we would also need - * to change the method's implementation and add a new instanceof-check. This violates the single - * responsibility principle - a class should have only one reason to change. + * One way to implement this would be to create multiple instanceof-checks for the methods parameter. However, this + * creates a maintenance issue. When new types are added we would also need to change the method's implementation and + * add a new instanceof-check. This violates the single responsibility principle - a class should have only one reason + * to change. *

- * Instead of the instanceof-checks a better way is to make another virtual call on the parameter - * object. This way new functionality can be easily added without the need to modify existing - * implementation (open-closed principle). + * Instead of the instanceof-checks a better way is to make another virtual call on the parameter object. This way new + * functionality can be easily added without the need to modify existing implementation (open-closed principle). *

- * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. - * Each object has its own coordinates which are checked against the other objects' coordinates. If - * there is an overlap, then the objects collide utilizing the Double Dispatch pattern. + * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each object has its + * own coordinates which are checked against the other objects' coordinates. If there is an overlap, then the objects + * collide utilizing the Double Dispatch pattern. * */ public class App { @@ -28,7 +26,8 @@ public class App { /** * Program entry point * - * @param args command line args + * @param args + * command line args */ public static void main(String[] args) { // initialize game objects and print their status @@ -42,8 +41,9 @@ public class App { // collision check objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { - if (o1 != o2 && o1.intersectsWith(o2)) + if (o1 != o2 && o1.intersectsWith(o2)) { o1.collision(o2); + } })); System.out.println(""); diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java index db26265cc..e1e3eab7b 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java @@ -12,6 +12,9 @@ public class Rectangle { private int right; private int bottom; + /** + * Constructor + */ public Rectangle(int left, int top, int right, int bottom) { this.left = left; this.top = top; diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java index 5a3366e4e..6792a5d37 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java @@ -107,9 +107,9 @@ public abstract class CollisionTest { final String targetName = target.getClass().getSimpleName(); final String otherName = other.getClass().getSimpleName(); - final String errorMessage = expectTargetOnFire ? - "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!" : - "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!"; + final String errorMessage = expectTargetOnFire + ? "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!" + : "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!"; assertEquals(errorMessage, expectTargetOnFire, target.isOnFire()); } @@ -126,9 +126,9 @@ public abstract class CollisionTest { final String targetName = target.getClass().getSimpleName(); final String otherName = other.getClass().getSimpleName(); - final String errorMessage = expectedDamage ? - "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!" : - "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!"; + final String errorMessage = expectedDamage + ? "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!" + : "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!"; assertEquals(errorMessage, expectedDamage, target.isDamaged()); } diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java index 09acf7442..bd13bd248 100644 --- a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java @@ -63,6 +63,37 @@ public abstract class EventEmitterTest { testAllDaysWithDefaultObserver(specialDay, event); } + /** + * Pass each week of the day, day by day to the event emitter and verify of the given observers + * received the correct event on the special day. + * + * @param specialDay The special day on which an event is emitted + * @param event The expected event emitted by the test object + * @param emitter The event emitter + * @param observers The registered observer mocks + */ + private void testAllDays(final Weekday specialDay, final Event event, final E emitter, + final EventObserver... observers) { + + for (final Weekday weekday : Weekday.values()) { + // Pass each week of the day, day by day to the event emitter + emitter.timePasses(weekday); + + if (weekday == specialDay) { + // On a special day, every observer should have received the event + for (final EventObserver observer : observers) { + verify(observer, times(1)).onEvent(eq(event)); + } + } else { + // On any other normal day, the observers should have received nothing at all + verifyZeroInteractions(observers); + } + } + + // The observers should not have received any additional events after the week + verifyNoMoreInteractions(observers); + } + /** * Go over every day of the month, and check if the event is emitted on the given day. Use an * event emitter without a default observer @@ -99,35 +130,4 @@ public abstract class EventEmitterTest { testAllDays(specialDay, event, emitter, defaultObserver, observer1, observer2); } - /** - * Pass each week of the day, day by day to the event emitter and verify of the given observers - * received the correct event on the special day. - * - * @param specialDay The special day on which an event is emitted - * @param event The expected event emitted by the test object - * @param emitter The event emitter - * @param observers The registered observer mocks - */ - private void testAllDays(final Weekday specialDay, final Event event, final E emitter, - final EventObserver... observers) { - - for (final Weekday weekday : Weekday.values()) { - // Pass each week of the day, day by day to the event emitter - emitter.timePasses(weekday); - - if (weekday == specialDay) { - // On a special day, every observer should have received the event - for (final EventObserver observer : observers) { - verify(observer, times(1)).onEvent(eq(event)); - } - } else { - // On any other normal day, the observers should have received nothing at all - verifyZeroInteractions(observers); - } - } - - // The observers should not have received any additional events after the week - verifyNoMoreInteractions(observers); - } - } diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java index 992ee4cf5..edec65b65 100644 --- a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java @@ -24,7 +24,7 @@ public class KingsHandTest extends EventEmitterTest { } /** - * The {@link KingsHand} is both an {@EventEmitter} as an {@link EventObserver} so verify if every + * The {@link KingsHand} is both an {@link EventEmitter} as an {@link EventObserver} so verify if every * event received is passed up to it's superior, in most cases {@link KingJoffrey} but now just a * mocked observer. */ diff --git a/execute-around/src/main/java/com/iluwatar/execute/around/App.java b/execute-around/src/main/java/com/iluwatar/execute/around/App.java index 4a0648dbe..4695b8df5 100644 --- a/execute-around/src/main/java/com/iluwatar/execute/around/App.java +++ b/execute-around/src/main/java/com/iluwatar/execute/around/App.java @@ -17,9 +17,6 @@ public class App { /** * Program entry point - * - * @param args command line args - * @throws IOException */ public static void main(String[] args) throws IOException { diff --git a/execute-around/src/main/java/com/iluwatar/execute/around/SimpleFileWriter.java b/execute-around/src/main/java/com/iluwatar/execute/around/SimpleFileWriter.java index be89ff9ce..e1a9073ef 100644 --- a/execute-around/src/main/java/com/iluwatar/execute/around/SimpleFileWriter.java +++ b/execute-around/src/main/java/com/iluwatar/execute/around/SimpleFileWriter.java @@ -11,6 +11,9 @@ import java.io.IOException; */ public class SimpleFileWriter { + /** + * Constructor + */ public SimpleFileWriter(String filename, FileWriterAction action) throws IOException { FileWriter writer = new FileWriter(filename); try { diff --git a/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java b/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java index 168026b65..0c959a716 100644 --- a/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java +++ b/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java @@ -65,11 +65,11 @@ public class SimpleFileWriterTest { * Verify if an {@link IOException} during the write ripples through */ @Test(expected = IOException.class) - public void testIOException() throws Exception { + public void testIoException() throws Exception { final File temporaryFile = this.testFolder.newFile(); new SimpleFileWriter(temporaryFile.getPath(), writer -> { - throw new IOException(""); - }); + throw new IOException(""); + }); } } diff --git a/facade/src/main/java/com/iluwatar/facade/DwarvenGoldmineFacade.java b/facade/src/main/java/com/iluwatar/facade/DwarvenGoldmineFacade.java index d6b653eaa..fd37e40c5 100644 --- a/facade/src/main/java/com/iluwatar/facade/DwarvenGoldmineFacade.java +++ b/facade/src/main/java/com/iluwatar/facade/DwarvenGoldmineFacade.java @@ -16,6 +16,9 @@ public class DwarvenGoldmineFacade { private final List workers; + /** + * Constructor + */ public DwarvenGoldmineFacade() { workers = new ArrayList<>(); workers.add(new DwarvenGoldDigger()); diff --git a/facade/src/main/java/com/iluwatar/facade/DwarvenMineWorker.java b/facade/src/main/java/com/iluwatar/facade/DwarvenMineWorker.java index d329fe84b..3190c9365 100644 --- a/facade/src/main/java/com/iluwatar/facade/DwarvenMineWorker.java +++ b/facade/src/main/java/com/iluwatar/facade/DwarvenMineWorker.java @@ -46,6 +46,9 @@ public abstract class DwarvenMineWorker { } } + /** + * Perform actions + */ public void action(Action... actions) { for (Action action : actions) { action(action); diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java index bdff83e17..cb5254f91 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java @@ -1,15 +1,19 @@ package com.iluwatar.fluentinterface.app; +import static java.lang.String.valueOf; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.StringJoiner; +import java.util.function.Function; +import java.util.function.Predicate; + import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable; import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable; -import java.util.*; -import java.util.function.Function; -import java.util.function.Predicate; - -import static java.lang.String.valueOf; - /** * The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. * Those interfaces tend to mimic domain specific languages, so they can nearly be read as human @@ -24,6 +28,9 @@ import static java.lang.String.valueOf; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { List integerList = new ArrayList<>(); diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java index e80356d8e..dae300c4e 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java @@ -5,8 +5,6 @@ import java.util.Iterator; /** * This class is used to realize LazyFluentIterables. It decorates a given iterator. Does not * support consecutive hasNext() calls. - * - * @param */ public abstract class DecoratingIterator implements Iterator { @@ -16,8 +14,6 @@ public abstract class DecoratingIterator implements Iterator { /** * Creates an iterator that decorates the given iterator. - * - * @param fromIterator */ public DecoratingIterator(Iterator fromIterator) { this.fromIterator = fromIterator; diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java index 19283152e..ef1859529 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java @@ -1,12 +1,16 @@ package com.iluwatar.fluentinterface.fluentiterable.simple; -import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; - -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; + /** * This is a simple implementation of the FluentIterable interface. It evaluates all chained * operations eagerly. This implementation would be costly to be utilized in real applications. diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java index 7d4cb0530..9159e90b0 100644 --- a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java +++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java @@ -26,7 +26,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; public abstract class FluentIterableTest { /** - * Create a new {@link FluentIterable} from the given integers + * Create a new {@link FluentIterable} from the given integers * * @param integers The integers * @return The new iterable, use for testing diff --git a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java index 26c836b0e..1ff624e11 100644 --- a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java +++ b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java @@ -31,6 +31,9 @@ public class Dispatcher { stores.add(store); } + /** + * Menu item selected handler + */ public void menuItemSelected(MenuItem menuItem) { dispatchAction(new MenuAction(menuItem)); switch (menuItem) { diff --git a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java index a48abbcb0..8418e01e6 100644 --- a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java +++ b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java @@ -14,6 +14,9 @@ public class AlchemistShop { private List topShelf; private List bottomShelf; + /** + * Constructor + */ public AlchemistShop() { topShelf = new ArrayList<>(); bottomShelf = new ArrayList<>(); @@ -58,6 +61,9 @@ public class AlchemistShop { return Collections.unmodifiableList(this.bottomShelf); } + /** + * Enumerate potions + */ public void enumerate() { System.out.println("Enumerating top shelf potions\n"); diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/App.java b/front-controller/src/main/java/com/iluwatar/front/controller/App.java index 18a92d37d..1beac119c 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/App.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/App.java @@ -2,32 +2,34 @@ package com.iluwatar.front.controller; /** * - * The Front Controller is a presentation tier pattern. Essentially it defines a - * controller that handles all requests for a web site. + * The Front Controller is a presentation tier pattern. Essentially it defines a controller that + * handles all requests for a web site. *

- * The Front Controller pattern consolidates request handling through a single handler - * object ({@link FrontController}). This object can carry out the common the behavior such as + * The Front Controller pattern consolidates request handling through a single handler object ( + * {@link FrontController}). This object can carry out the common the behavior such as * authorization, request logging and routing requests to corresponding views. *

- * Typically the requests are mapped to command objects ({@link Command}) which then display - * the correct view ({@link View}). + * Typically the requests are mapped to command objects ({@link Command}) which then display the + * correct view ({@link View}). *

* In this example we have implemented two views: {@link ArcherView} and {@link CatapultView}. These - * are displayed by sending correct request to the {@link FrontController} object. For example, - * the {@link ArcherView} gets displayed when {@link FrontController} receives request "Archer". When + * are displayed by sending correct request to the {@link FrontController} object. For example, the + * {@link ArcherView} gets displayed when {@link FrontController} receives request "Archer". When * the request is unknown, we display the error view ({@link ErrorView}). * */ public class App { - - /** - * Program entry point - * @param args command line args - */ - public static void main(String[] args) { - FrontController controller = new FrontController(); - controller.handleRequest("Archer"); - controller.handleRequest("Catapult"); - controller.handleRequest("foobar"); - } + + /** + * Program entry point + * + * @param args + * command line args + */ + public static void main(String[] args) { + FrontController controller = new FrontController(); + controller.handleRequest("Archer"); + controller.handleRequest("Catapult"); + controller.handleRequest("foobar"); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/ApplicationException.java b/front-controller/src/main/java/com/iluwatar/front/controller/ApplicationException.java index b3963d8e9..bb44d34f0 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/ApplicationException.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/ApplicationException.java @@ -7,9 +7,9 @@ package com.iluwatar.front.controller; */ public class ApplicationException extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public ApplicationException(Throwable cause) { - super(cause); - } + public ApplicationException(Throwable cause) { + super(cause); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/ArcherCommand.java b/front-controller/src/main/java/com/iluwatar/front/controller/ArcherCommand.java index 117aa0c8c..8396d5cfc 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/ArcherCommand.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/ArcherCommand.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class ArcherCommand implements Command { - @Override - public void process() { - new ArcherView().display(); - } + @Override + public void process() { + new ArcherView().display(); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/ArcherView.java b/front-controller/src/main/java/com/iluwatar/front/controller/ArcherView.java index d8cae33c1..d16fe8b71 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/ArcherView.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/ArcherView.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class ArcherView implements View { - @Override - public void display() { - System.out.println("Displaying archers"); - } + @Override + public void display() { + System.out.println("Displaying archers"); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/CatapultCommand.java b/front-controller/src/main/java/com/iluwatar/front/controller/CatapultCommand.java index fae5d1753..b5ad9e37c 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/CatapultCommand.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/CatapultCommand.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class CatapultCommand implements Command { - @Override - public void process() { - new CatapultView().display(); - } + @Override + public void process() { + new CatapultView().display(); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/CatapultView.java b/front-controller/src/main/java/com/iluwatar/front/controller/CatapultView.java index 9ad94d522..161b4ed4e 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/CatapultView.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/CatapultView.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class CatapultView implements View { - @Override - public void display() { - System.out.println("Displaying catapults"); - } + @Override + public void display() { + System.out.println("Displaying catapults"); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/Command.java b/front-controller/src/main/java/com/iluwatar/front/controller/Command.java index 95bd00129..2ad41a629 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/Command.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/Command.java @@ -6,6 +6,6 @@ package com.iluwatar.front.controller; * */ public interface Command { - - void process(); + + void process(); } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/ErrorView.java b/front-controller/src/main/java/com/iluwatar/front/controller/ErrorView.java index 04c31dd34..c1045c821 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/ErrorView.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/ErrorView.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class ErrorView implements View { - @Override - public void display() { - System.out.println("Error 500"); - } + @Override + public void display() { + System.out.println("Error 500"); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/FrontController.java b/front-controller/src/main/java/com/iluwatar/front/controller/FrontController.java index 0c6c132f2..6b84d7f78 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/FrontController.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/FrontController.java @@ -2,33 +2,33 @@ package com.iluwatar.front.controller; /** * - * FrontController is the handler class that takes in all the requests and - * renders the correct response. + * FrontController is the handler class that takes in all the requests and renders the correct + * response. * */ public class FrontController { - - public void handleRequest(String request) { - Command command = getCommand(request); - command.process(); - } - - private Command getCommand(String request) { - Class commandClass = getCommandClass(request); - try { - return (Command) commandClass.newInstance(); - } catch (Exception e) { - throw new ApplicationException(e); - } - } - - private Class getCommandClass(String request) { - Class result; - try { - result = Class.forName("com.iluwatar.front.controller." + request + "Command"); - } catch (ClassNotFoundException e) { - result = UnknownCommand.class; - } - return result; - } + + public void handleRequest(String request) { + Command command = getCommand(request); + command.process(); + } + + private Command getCommand(String request) { + Class commandClass = getCommandClass(request); + try { + return (Command) commandClass.newInstance(); + } catch (Exception e) { + throw new ApplicationException(e); + } + } + + private Class getCommandClass(String request) { + Class result; + try { + result = Class.forName("com.iluwatar.front.controller." + request + "Command"); + } catch (ClassNotFoundException e) { + result = UnknownCommand.class; + } + return result; + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/UnknownCommand.java b/front-controller/src/main/java/com/iluwatar/front/controller/UnknownCommand.java index f8f93e7e0..d800d4db0 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/UnknownCommand.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/UnknownCommand.java @@ -7,8 +7,8 @@ package com.iluwatar.front.controller; */ public class UnknownCommand implements Command { - @Override - public void process() { - new ErrorView().display(); - } + @Override + public void process() { + new ErrorView().display(); + } } diff --git a/front-controller/src/main/java/com/iluwatar/front/controller/View.java b/front-controller/src/main/java/com/iluwatar/front/controller/View.java index 29c5f0fcb..55bb187ce 100644 --- a/front-controller/src/main/java/com/iluwatar/front/controller/View.java +++ b/front-controller/src/main/java/com/iluwatar/front/controller/View.java @@ -7,5 +7,5 @@ package com.iluwatar.front.controller; */ public interface View { - void display(); + void display(); } diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java index 2c28aa8ce..f858a797d 100644 --- a/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java +++ b/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java @@ -10,10 +10,10 @@ import com.iluwatar.front.controller.App; * */ public class AppTest { - - @Test - public void test() { - String[] args = {}; - App.main(args); - } + + @Test + public void test() { + String[] args = {}; + App.main(args); + } } diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java index 18bdf0d13..4b038cfda 100644 --- a/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java +++ b/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java @@ -1,8 +1,8 @@ package com.iluwatar.front.controller; -import org.junit.Test; +import static org.junit.Assert.assertSame; -import static org.junit.Assert.*; +import org.junit.Test; /** * Date: 12/13/15 - 1:35 PM diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java index 80f2eefb2..b67b602ca 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java @@ -21,17 +21,15 @@ import java.util.concurrent.LinkedBlockingQueue; * *

* APPLICABILITY
- *

    - *
  • UNIX network subsystems - In operating systems network operations are carried out - * asynchronously with help of hardware level interrupts.
  • - *
  • CORBA - At the asynchronous layer one thread is associated with each socket that is connected + * UNIX network subsystems - In operating systems network operations are carried out + * asynchronously with help of hardware level interrupts.
    + * CORBA - At the asynchronous layer one thread is associated with each socket that is connected * to the client. Thread blocks waiting for CORBA requests from the client. On receiving request it * is inserted in the queuing layer which is then picked up by synchronous layer which processes the - * request and sends response back to the client.
  • - *
  • Android AsyncTask framework - Framework provides a way to execute long running blocking + * request and sends response back to the client.
    + * Android AsyncTask framework - Framework provides a way to execute long running blocking * calls, such as downloading a file, in background threads so that the UI thread remains free to - * respond to user inputs. - *
+ * respond to user inputs.
* *

* IMPLEMENTATION
@@ -121,6 +119,7 @@ public class App { try { Thread.sleep(i); } catch (InterruptedException e) { + System.out.println(e); } return (i) * (i + 1) / 2; } diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/AddressFilter.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/AddressFilter.java index c1aa0780b..38a762483 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/AddressFilter.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/AddressFilter.java @@ -14,7 +14,8 @@ public class AddressFilter extends AbstractFilter { String result = super.execute(order); if (order.getAddress() == null || order.getAddress().isEmpty()) { return result + "Invalid address! "; - } else + } else { return result; + } } } diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java index 02499ed0a..5934da75c 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java @@ -32,8 +32,12 @@ public class Client extends JFrame { private JLabel jl; private JTextField[] jtFields; private JTextArea[] jtAreas; - private JButton clearButton, processButton; + private JButton clearButton; + private JButton processButton; + /** + * Constructor + */ public Client() { super("Client System"); setDefaultCloseOperation(EXIT_ON_CLOSE); diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Filter.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Filter.java index 9496bde36..a1ea5b4ee 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Filter.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Filter.java @@ -11,30 +11,21 @@ public interface Filter { /** * Execute order processing filter. - * - * @param order - * @return empty string on success, otherwise error message. */ String execute(Order order); /** * Set next filter in chain after this. - * - * @param filter */ void setNext(Filter filter); /** * Get next filter in chain after this. - * - * @return */ Filter getNext(); /** * Get last filter in the chain. - * - * @return */ Filter getLast(); } diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterChain.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterChain.java index 987678cc7..b180579d2 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterChain.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterChain.java @@ -12,10 +12,16 @@ public class FilterChain { private final Target target; + /** + * Constructor + */ public FilterChain(Target target) { this.target = target; } + /** + * Adds filter + */ public void addFilter(Filter filter) { if (chain == null) { chain = filter; @@ -24,6 +30,9 @@ public class FilterChain { } } + /** + * Execute filter chain + */ public String execute(Order order) { if (chain != null) { return chain.execute(order); diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Order.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Order.java index 5b30fee35..53d1a3dd9 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Order.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Order.java @@ -14,6 +14,9 @@ public class Order { public Order() {} + /** + * Constructor + */ public Order(String name, String contactNumber, String address, String depositNumber, String order) { this.name = name; this.contactNumber = contactNumber; diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java index cb96cd6e0..ffb13c160 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java @@ -29,6 +29,9 @@ public class Target extends JFrame { private DefaultTableModel dtm; private JButton del; + /** + * Constructor + */ public Target() { super("Order System"); setDefaultCloseOperation(EXIT_ON_CLOSE); @@ -67,8 +70,9 @@ public class Target extends JFrame { @Override public void actionPerformed(ActionEvent e) { int temp = jt.getSelectedRow(); - if (temp == -1) + if (temp == -1) { return; + } int temp2 = jt.getSelectedRowCount(); for (int i = 0; i < temp2; i++) { dtm.removeRow(temp); diff --git a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java index f15760f08..71d9bf250 100644 --- a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java +++ b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java @@ -73,6 +73,9 @@ public class FilterTest { private final Order order; private final String result; + /** + * Constructor + */ public FilterTest(Filter filter, Order order, String result) { this.filter = filter; this.order = order; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/App.java b/interpreter/src/main/java/com/iluwatar/interpreter/App.java index 2f88951f1..e4e238c15 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/App.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/App.java @@ -55,6 +55,9 @@ public class App { return s.equals("+") || s.equals("-") || s.equals("*"); } + /** + * Get expression for string + */ public static Expression getOperatorInstance(String s, Expression left, Expression right) { switch (s) { case "+": @@ -63,7 +66,8 @@ public class App { return new MinusExpression(left, right); case "*": return new MultiplyExpression(left, right); + default: + return new MultiplyExpression(left, right); } - return null; } } diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java index 2cdee9966..150596cd8 100644 --- a/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java +++ b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java @@ -27,9 +27,9 @@ public abstract class ExpressionTest { for (int i = -10; i < 10; i++) { for (int j = -10; j < 10; j++) { testData.add(new Object[]{ - new NumberExpression(i), - new NumberExpression(j), - resultCalc.apply(i, j) + new NumberExpression(i), + new NumberExpression(j), + resultCalc.apply(i, j) }); } } diff --git a/iterator/src/main/java/com/iluwatar/iterator/App.java b/iterator/src/main/java/com/iluwatar/iterator/App.java index c9c5fa521..467040ca6 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/App.java +++ b/iterator/src/main/java/com/iluwatar/iterator/App.java @@ -20,28 +20,28 @@ public class App { public static void main(String[] args) { TreasureChest chest = new TreasureChest(); - ItemIterator ringIterator = chest.Iterator(ItemType.RING); + ItemIterator ringIterator = chest.iterator(ItemType.RING); while (ringIterator.hasNext()) { System.out.println(ringIterator.next()); } System.out.println("----------"); - ItemIterator potionIterator = chest.Iterator(ItemType.POTION); + ItemIterator potionIterator = chest.iterator(ItemType.POTION); while (potionIterator.hasNext()) { System.out.println(potionIterator.next()); } System.out.println("----------"); - ItemIterator weaponIterator = chest.Iterator(ItemType.WEAPON); + ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON); while (weaponIterator.hasNext()) { System.out.println(weaponIterator.next()); } System.out.println("----------"); - ItemIterator it = chest.Iterator(ItemType.ANY); + ItemIterator it = chest.iterator(ItemType.ANY); while (it.hasNext()) { System.out.println(it.next()); } diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java b/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java index 02496e33c..6b5c54a5a 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java +++ b/iterator/src/main/java/com/iluwatar/iterator/TreasureChest.java @@ -12,6 +12,9 @@ public class TreasureChest { private List items; + /** + * Constructor + */ public TreasureChest() { items = new ArrayList<>(); items.add(new Item(ItemType.POTION, "Potion of courage")); @@ -26,10 +29,13 @@ public class TreasureChest { items.add(new Item(ItemType.WEAPON, "Dagger of poison")); } - ItemIterator Iterator(ItemType type) { - return new TreasureChestItemIterator(this, type); + ItemIterator iterator(ItemType itemType) { + return new TreasureChestItemIterator(this, itemType); } + /** + * Get all items + */ public List getItems() { ArrayList list = new ArrayList<>(); list.addAll(items); diff --git a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java index 39c12ab44..a8303f308 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/TreasureChestItemIterator.java @@ -13,6 +13,9 @@ public class TreasureChestItemIterator implements ItemIterator { private int idx; private ItemType type; + /** + * Constructor + */ public TreasureChestItemIterator(TreasureChest chest, ItemType type) { this.chest = chest; this.type = type; diff --git a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java b/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java index a32066ea8..a2102a2e2 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java @@ -60,7 +60,7 @@ public class TreasureChestTest { @Test public void testIterator() { final TreasureChest chest = new TreasureChest(); - final ItemIterator iterator = chest.Iterator(expectedItem.getType()); + final ItemIterator iterator = chest.iterator(expectedItem.getType()); assertNotNull(iterator); while (iterator.hasNext()) { diff --git a/layers/src/main/java/com/iluwatar/layers/App.java b/layers/src/main/java/com/iluwatar/layers/App.java index d175553f7..ecb532510 100644 --- a/layers/src/main/java/com/iluwatar/layers/App.java +++ b/layers/src/main/java/com/iluwatar/layers/App.java @@ -4,31 +4,31 @@ import java.util.Arrays; /** * - * Layers is an architectural style where software responsibilities are divided among the different - * layers of the application. + * Layers is an architectural style where software responsibilities are divided among the different layers of the + * application. *

- * This example demonstrates a traditional 3-layer architecture consisting of data access layer, - * business layer and presentation layer. + * This example demonstrates a traditional 3-layer architecture consisting of data access layer, business layer and + * presentation layer. *

- * The data access layer is formed of Spring Data repositories CakeDao, - * CakeToppingDao and CakeLayerDao. The repositories can be used for CRUD - * operations on cakes, cake toppings and cake layers respectively. + * The data access layer is formed of Spring Data repositories CakeDao, CakeToppingDao and + * CakeLayerDao. The repositories can be used for CRUD operations on cakes, cake toppings and cake layers + * respectively. *

- * The business layer is built on top of the data access layer. CakeBakingService - * offers methods to retrieve available cake toppings and cake layers and baked cakes. Also the - * service is used to create new cakes out of cake toppings and cake layers. + * The business layer is built on top of the data access layer. CakeBakingService offers methods to + * retrieve available cake toppings and cake layers and baked cakes. Also the service is used to create new cakes out of + * cake toppings and cake layers. *

- * The presentation layer is built on the business layer and in this example it simply lists the - * cakes that have been baked. + * The presentation layer is built on the business layer and in this example it simply lists the cakes that have been + * baked. *

- * We have applied so called strict layering which means that the layers can only access the classes - * directly beneath them. This leads the solution to create an additional set of DTOs ( - * CakeInfo, CakeToppingInfo, CakeLayerInfo) to translate - * data between layers. In other words, CakeBakingService cannot return entities ( - * Cake, CakeTopping, CakeLayer) directly since these reside - * on data access layer but instead translates these into business layer DTOs (CakeInfo, CakeToppingInfo, CakeLayerInfo) and returns them instead. This way - * the presentation layer does not have any knowledge of other layers than the business layer and - * thus is not affected by changes to them. + * We have applied so called strict layering which means that the layers can only access the classes directly beneath + * them. This leads the solution to create an additional set of DTOs ( CakeInfo, + * CakeToppingInfo, CakeLayerInfo) to translate data between layers. In other words, + * CakeBakingService cannot return entities ( Cake, CakeTopping, + * CakeLayer) directly since these reside on data access layer but instead translates these into business + * layer DTOs (CakeInfo, CakeToppingInfo, CakeLayerInfo) and returns them + * instead. This way the presentation layer does not have any knowledge of other layers than the business layer and thus + * is not affected by changes to them. * * @see Cake * @see CakeTopping @@ -63,8 +63,6 @@ public class App { /** * Initializes the example data - * - * @param cakeBakingService */ private static void initializeData(CakeBakingService cakeBakingService) { cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200)); diff --git a/layers/src/main/java/com/iluwatar/layers/CakeBakingService.java b/layers/src/main/java/com/iluwatar/layers/CakeBakingService.java index 80bd3438b..adfa585d6 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeBakingService.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeBakingService.java @@ -11,44 +11,31 @@ public interface CakeBakingService { /** * Bakes new cake according to parameters - * - * @param cakeInfo - * @throws CakeBakingException */ void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException; /** * Get all cakes - * - * @return */ List getAllCakes(); /** * Store new cake topping - * - * @param toppingInfo */ void saveNewTopping(CakeToppingInfo toppingInfo); /** * Get available cake toppings - * - * @return */ List getAvailableToppings(); /** * Add new cake layer - * - * @param layerInfo */ void saveNewLayer(CakeLayerInfo layerInfo); /** * Get available cake layers - * - * @return */ List getAvailableLayers(); } diff --git a/layers/src/main/java/com/iluwatar/layers/CakeInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeInfo.java index f60ee9a14..6ae5008f0 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeInfo.java @@ -14,18 +14,27 @@ public class CakeInfo { public final CakeToppingInfo cakeToppingInfo; public final List cakeLayerInfos; + /** + * Constructor + */ public CakeInfo(Long id, CakeToppingInfo cakeToppingInfo, List cakeLayerInfos) { this.id = Optional.of(id); this.cakeToppingInfo = cakeToppingInfo; this.cakeLayerInfos = cakeLayerInfos; } + /** + * Constructor + */ public CakeInfo(CakeToppingInfo cakeToppingInfo, List cakeLayerInfos) { this.id = Optional.empty(); this.cakeToppingInfo = cakeToppingInfo; this.cakeLayerInfos = cakeLayerInfos; } + /** + * Calculate calories + */ public int calculateTotalCalories() { int total = cakeToppingInfo != null ? cakeToppingInfo.calories : 0; total += cakeLayerInfos.stream().mapToInt(c -> c.calories).sum(); diff --git a/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java index 3dff379da..339a61b4e 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeLayerInfo.java @@ -13,12 +13,18 @@ public class CakeLayerInfo { public final String name; public final int calories; + /** + * Constructor + */ public CakeLayerInfo(Long id, String name, int calories) { this.id = Optional.of(id); this.name = name; this.calories = calories; } + /** + * Constructor + */ public CakeLayerInfo(String name, int calories) { this.id = Optional.empty(); this.name = name; diff --git a/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java b/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java index 4e432ec44..726d597d2 100644 --- a/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java +++ b/layers/src/main/java/com/iluwatar/layers/CakeToppingInfo.java @@ -13,12 +13,18 @@ public class CakeToppingInfo { public final String name; public final int calories; + /** + * Constructor + */ public CakeToppingInfo(Long id, String name, int calories) { this.id = Optional.of(id); this.name = name; this.calories = calories; } + /** + * Constructor + */ public CakeToppingInfo(String name, int calories) { this.id = Optional.empty(); this.name = name; diff --git a/layers/src/main/resources/META-INF/persistence.xml b/layers/src/main/resources/META-INF/persistence.xml index d94d8582b..96856e1b9 100644 --- a/layers/src/main/resources/META-INF/persistence.xml +++ b/layers/src/main/resources/META-INF/persistence.xml @@ -1,8 +1,8 @@ + xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> - + \ No newline at end of file diff --git a/layers/src/main/resources/applicationContext.xml b/layers/src/main/resources/applicationContext.xml index 0c908ad2e..6b3bc466d 100644 --- a/layers/src/main/resources/applicationContext.xml +++ b/layers/src/main/resources/applicationContext.xml @@ -1,42 +1,39 @@ - + - + - + - - - + + + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Heavy.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Heavy.java index 25e46d8b9..dabd8c313 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Heavy.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Heavy.java @@ -7,6 +7,9 @@ package com.iluwatar.lazy.loading; */ public class Heavy { + /** + * Constructor + */ public Heavy() { System.out.println("Creating Heavy ..."); try { diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderNaive.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderNaive.java index 132ebaa5f..f78005c73 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderNaive.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderNaive.java @@ -9,10 +9,16 @@ public class HolderNaive { private Heavy heavy; + /** + * Constructor + */ public HolderNaive() { System.out.println("HolderNaive created"); } + /** + * Get heavy object + */ public Heavy getHeavy() { if (heavy == null) { heavy = new Heavy(); diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderThreadSafe.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderThreadSafe.java index d2b15a3af..56074846e 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderThreadSafe.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/HolderThreadSafe.java @@ -10,10 +10,16 @@ public class HolderThreadSafe { private Heavy heavy; + /** + * Constructor + */ public HolderThreadSafe() { System.out.println("HolderThreadSafe created"); } + /** + * Get heavy object + */ public synchronized Heavy getHeavy() { if (heavy == null) { heavy = new Heavy(); diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java index da021e014..aa86e3b34 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java @@ -5,7 +5,7 @@ import java.util.function.Supplier; /** * * This lazy loader is thread safe and more efficient than {@link HolderThreadSafe}. It utilizes - * Java 8 functional interface {@link Supplier} as {@link Heavy} factory. + * Java 8 functional interface {@link Supplier} as {@link Heavy} factory. * */ public class Java8Holder { diff --git a/memento/src/main/java/com/iluwatar/memento/App.java b/memento/src/main/java/com/iluwatar/memento/App.java index c99894680..e08e9a106 100644 --- a/memento/src/main/java/com/iluwatar/memento/App.java +++ b/memento/src/main/java/com/iluwatar/memento/App.java @@ -23,6 +23,9 @@ import java.util.Stack; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { Stack states = new Stack<>(); diff --git a/memento/src/main/java/com/iluwatar/memento/Star.java b/memento/src/main/java/com/iluwatar/memento/Star.java index b4ec1c669..f67edfd15 100644 --- a/memento/src/main/java/com/iluwatar/memento/Star.java +++ b/memento/src/main/java/com/iluwatar/memento/Star.java @@ -11,12 +11,18 @@ public class Star { private int ageYears; private int massTons; + /** + * Constructor + */ public Star(StarType startType, int startAge, int startMass) { this.type = startType; this.ageYears = startAge; this.massTons = startMass; } + /** + * Makes time pass for the star + */ public void timePasses() { ageYears *= 2; massTons *= 8; diff --git a/message-channel/src/main/java/com/iluwatar/message/channel/App.java b/message-channel/src/main/java/com/iluwatar/message/channel/App.java index a41dd74dc..b0aeb690f 100644 --- a/message-channel/src/main/java/com/iluwatar/message/channel/App.java +++ b/message-channel/src/main/java/com/iluwatar/message/channel/App.java @@ -30,9 +30,6 @@ public class App { /** * Program entry point - * - * @param args command line args - * @throws Exception */ public static void main(String[] args) throws Exception { CamelContext context = new DefaultCamelContext(); diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java index d04f284ac..0cf4f8c34 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java @@ -39,9 +39,7 @@ public class FileLoader { br.close(); return sb.toString(); - } - - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 02cb2703a..6f220cffb 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -26,7 +26,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /** * The "OK" button for loading the file. */ - private JButton OK; + private JButton ok; /** * The cancel button. @@ -121,10 +121,10 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /* * Add the OK button. */ - this.OK = new JButton("OK"); - this.panel.add(OK); - this.OK.setBounds(250, 50, 100, 25); - this.OK.addActionListener(this); + this.ok = new JButton("OK"); + this.panel.add(ok); + this.ok.setBounds(250, 50, 100, 25); + this.ok.addActionListener(this); /* * Add the cancel button. @@ -140,13 +140,11 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti @Override public void actionPerformed(ActionEvent e) { - if (e.getSource() == this.OK) { + if (e.getSource() == this.ok) { this.fileName = this.input.getText(); presenter.fileNameChanged(); presenter.confirmed(); - } - - else if (e.getSource() == this.cancel) { + } else if (e.getSource() == this.cancel) { presenter.cancelled(); } } diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java index 133d8555d..f38dc2655 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java @@ -51,6 +51,9 @@ public class FileSelectorPresenter { loader.setFileName(view.getFileName()); } + /** + * Ok button handler + */ public void confirmed() { if (loader.getFileName() == null || loader.getFileName().equals("")) { view.showMessage("Please give the name of the file first!"); @@ -60,9 +63,7 @@ public class FileSelectorPresenter { if (loader.fileExists()) { String data = loader.loadData(); view.displayData(data); - } - - else { + } else { view.showMessage("The file specified does not exist."); } } diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java index dfdcba31b..ba371525a 100644 --- a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java @@ -1,14 +1,13 @@ package com.iluwatar.model.view.presenter; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; -import com.iluwatar.model.view.presenter.FileLoader; -import com.iluwatar.model.view.presenter.FileSelectorPresenter; -import com.iluwatar.model.view.presenter.FileSelectorStub; - /** * This test case is responsible for testing our application by taking advantage of the * Model-View-Controller architectural pattern. @@ -57,13 +56,13 @@ public class FileSelectorPresenterTest { */ @Test public void updateFileNameToLoader() { - String EXPECTED_FILE = "Stamatis"; - stub.setFileName(EXPECTED_FILE); + String expectedFile = "Stamatis"; + stub.setFileName(expectedFile); presenter.start(); presenter.fileNameChanged(); - assertEquals(EXPECTED_FILE, loader.getFileName()); + assertEquals(expectedFile, loader.getFileName()); } /** diff --git a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java index b81e44251..429eda73e 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java +++ b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java @@ -24,6 +24,9 @@ public class LoadBalancer { servers.add(new Server("localhost", 8084, ++id)); } + /** + * Add new server + */ public final void addServer(Server server) { synchronized (servers) { servers.add(server); @@ -39,6 +42,9 @@ public class LoadBalancer { return lastServedId; } + /** + * Handle request + */ public void serverequest(Request request) { if (lastServedId >= servers.size()) { lastServedId = 0; diff --git a/monostate/src/main/java/com/iluwatar/monostate/Server.java b/monostate/src/main/java/com/iluwatar/monostate/Server.java index f48f4ad0f..21794de42 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/Server.java +++ b/monostate/src/main/java/com/iluwatar/monostate/Server.java @@ -11,6 +11,9 @@ public class Server { public final int port; public final int id; + /** + * Constructor + */ public Server(String host, int port, int id) { this.host = host; this.port = port; diff --git a/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageService.java b/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageService.java index 6769f95dd..fa1e74048 100644 --- a/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageService.java +++ b/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageService.java @@ -21,9 +21,7 @@ import org.apache.isis.applib.annotation.HomePage; import org.apache.isis.applib.annotation.NatureOfService; import org.apache.isis.applib.annotation.SemanticsOf; -@DomainService(nature = NatureOfService.VIEW_CONTRIBUTIONS_ONLY // trick to suppress the actions - // from the top-level menu -) +@DomainService(nature = NatureOfService.VIEW_CONTRIBUTIONS_ONLY) public class HomePageService { // region > homePage (action) diff --git a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObjects.java b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObjects.java index 5e4642455..849f01c5d 100644 --- a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObjects.java +++ b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObjects.java @@ -69,9 +69,12 @@ public class SimpleObjects { } } + /** + * Create simple object + */ @Action(domainEvent = CreateDomainEvent.class) @MemberOrder(sequence = "3") - public SimpleObject create(final @ParameterLayout(named = "Name") String name) { + public SimpleObject create(@ParameterLayout(named = "Name") final String name) { final SimpleObject obj = container.newTransientInstance(SimpleObject.class); obj.setName(name); container.persistIfNotAlready(obj); diff --git a/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java b/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java index 2918fe7f6..266529c74 100644 --- a/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java +++ b/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java @@ -45,8 +45,6 @@ public class SimpleObjectCreate extends FixtureScript { /** * The created simple object (output). - * - * @return */ public SimpleObject getSimpleObject() { return simpleObject; diff --git a/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java b/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java index c978e0b82..c82ef8498 100644 --- a/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java +++ b/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java @@ -29,7 +29,7 @@ import domainapp.fixture.modules.simple.SimpleObjectsTearDown; public class RecreateSimpleObjects extends FixtureScript { - public final List NAMES = Collections.unmodifiableList(Arrays.asList("Foo", "Bar", "Baz", + public final List names = Collections.unmodifiableList(Arrays.asList("Foo", "Bar", "Baz", "Frodo", "Froyo", "Fizz", "Bip", "Bop", "Bang", "Boo")); public RecreateSimpleObjects() { @@ -72,9 +72,9 @@ public class RecreateSimpleObjects extends FixtureScript { final int number = defaultParam("number", ec, 3); // validate - if (number < 0 || number > NAMES.size()) { + if (number < 0 || number > names.size()) { throw new IllegalArgumentException(String.format("number must be in range [0,%d)", - NAMES.size())); + names.size())); } // @@ -83,7 +83,7 @@ public class RecreateSimpleObjects extends FixtureScript { ec.executeChild(this, new SimpleObjectsTearDown()); for (int i = 0; i < number; i++) { - final SimpleObjectCreate fs = new SimpleObjectCreate().setName(NAMES.get(i)); + final SimpleObjectCreate fs = new SimpleObjectCreate().setName(names.get(i)); ec.executeChild(this, fs.getName(), fs); simpleObjects.add(fs.getSimpleObject()); } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java index c617915f1..0384b0eb4 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java @@ -21,6 +21,9 @@ import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegT public class SimpleAppSystemInitializer { + /** + * Init test system + */ public static void initIsft() { IsisSystemForTest isft = IsisSystemForTest.getElseNull(); if (isft == null) { diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java index ef6012919..2ea375b4a 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java @@ -29,7 +29,7 @@ import static org.junit.Assert.assertThat; public class SimpleObjectGlue extends CukeGlueAbstract { @Given("^there are.* (\\d+) simple objects$") - public void there_are_N_simple_objects(int n) throws Throwable { + public void thereAreNumSimpleObjects(int n) throws Throwable { try { final List findAll = service(SimpleObjects.class).listAll(); assertThat(findAll.size(), is(n)); @@ -41,7 +41,7 @@ public class SimpleObjectGlue extends CukeGlueAbstract { } @When("^I create a new simple object$") - public void I_create_a_new_simple_object() throws Throwable { + public void createNewSimpleObject() throws Throwable { service(SimpleObjects.class).create(UUID.randomUUID().toString()); } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/SimpleAppIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/SimpleAppIntegTest.java index 3ceef4e63..7a7ad91b2 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/SimpleAppIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/SimpleAppIntegTest.java @@ -27,13 +27,13 @@ import domainapp.integtests.bootstrap.SimpleAppSystemInitializer; public abstract class SimpleAppIntegTest extends IntegrationTestAbstract { - @BeforeClass - public static void initClass() { - org.apache.log4j.PropertyConfigurator.configure("logging.properties"); - SimpleAppSystemInitializer.initIsft(); + @BeforeClass + public static void initClass() { + org.apache.log4j.PropertyConfigurator.configure("logging.properties"); + SimpleAppSystemInitializer.initIsft(); - // instantiating will install onto ThreadLocal - new ScenarioExecutionForIntegration(); - } + // instantiating will install onto ThreadLocal + new ScenarioExecutionForIntegration(); + } } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java index 610136bb8..872aff7a3 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java @@ -35,87 +35,86 @@ import static org.assertj.core.api.Assertions.assertThat; public class SimpleObjectIntegTest extends SimpleAppIntegTest { + @Inject + FixtureScripts fixtureScripts; + + RecreateSimpleObjects fs; + SimpleObject simpleObjectPojo; + SimpleObject simpleObjectWrapped; + + @Before + public void setUp() throws Exception { + // given + fs = new RecreateSimpleObjects().setNumber(1); + fixtureScripts.runFixtureScript(fs, null); + + simpleObjectPojo = fs.getSimpleObjects().get(0); + + assertThat(simpleObjectPojo).isNotNull(); + simpleObjectWrapped = wrap(simpleObjectPojo); + } + + public static class Name extends SimpleObjectIntegTest { + + @Test + public void accessible() throws Exception { + // when + final String name = simpleObjectWrapped.getName(); + // then + assertThat(name).isEqualTo(fs.names.get(0)); + } + + @Test + public void cannotBeUpdatedDirectly() throws Exception { + + // expect + expectedExceptions.expect(DisabledException.class); + + // when + simpleObjectWrapped.setName("new name"); + } + } + + public static class UpdateName extends SimpleObjectIntegTest { + + @Test + public void happyCase() throws Exception { + + // when + simpleObjectWrapped.updateName("new name"); + + // then + assertThat(simpleObjectWrapped.getName()).isEqualTo("new name"); + } + + @Test + public void failsValidation() throws Exception { + + // expect + expectedExceptions.expect(InvalidException.class); + expectedExceptions.expectMessage("Exclamation mark is not allowed"); + + // when + simpleObjectWrapped.updateName("new name!"); + } + } + + public static class Title extends SimpleObjectIntegTest { + @Inject - FixtureScripts fixtureScripts; + DomainObjectContainer container; - RecreateSimpleObjects fs; - SimpleObject simpleObjectPojo; - SimpleObject simpleObjectWrapped; + @Test + public void interpolatesName() throws Exception { - @Before - public void setUp() throws Exception { - // given - fs = new RecreateSimpleObjects().setNumber(1); - fixtureScripts.runFixtureScript(fs, null); + // given + final String name = simpleObjectWrapped.getName(); - simpleObjectPojo = fs.getSimpleObjects().get(0); + // when + final String title = container.titleOf(simpleObjectWrapped); - assertThat(simpleObjectPojo).isNotNull(); - simpleObjectWrapped = wrap(simpleObjectPojo); - } - - public static class Name extends SimpleObjectIntegTest { - - @Test - public void accessible() throws Exception { - // when - final String name = simpleObjectWrapped.getName(); - // then - assertThat(name).isEqualTo(fs.NAMES.get(0)); - } - - @Test - public void cannotBeUpdatedDirectly() throws Exception { - - // expect - expectedExceptions.expect(DisabledException.class); - - // when - simpleObjectWrapped.setName("new name"); - } - } - - public static class UpdateName extends SimpleObjectIntegTest { - - @Test - public void happyCase() throws Exception { - - // when - simpleObjectWrapped.updateName("new name"); - - // then - assertThat(simpleObjectWrapped.getName()).isEqualTo("new name"); - } - - @Test - public void failsValidation() throws Exception { - - // expect - expectedExceptions.expect(InvalidException.class); - expectedExceptions.expectMessage("Exclamation mark is not allowed"); - - // when - simpleObjectWrapped.updateName("new name!"); - } - } - - - public static class Title extends SimpleObjectIntegTest { - - @Inject - DomainObjectContainer container; - - @Test - public void interpolatesName() throws Exception { - - // given - final String name = simpleObjectWrapped.getName(); - - // when - final String title = container.titleOf(simpleObjectWrapped); - - // then - assertThat(title).isEqualTo("Object: " + name); - } + // then + assertThat(title).isEqualTo("Object: " + name); } + } } \ No newline at end of file diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java index fd3b0ff46..332213542 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java @@ -42,102 +42,102 @@ import static org.assertj.core.api.Assertions.assertThat; public class SimpleObjectsIntegTest extends SimpleAppIntegTest { - @Inject - FixtureScripts fixtureScripts; - @Inject - SimpleObjects simpleObjects; + @Inject + FixtureScripts fixtureScripts; + @Inject + SimpleObjects simpleObjects; - public static class ListAll extends SimpleObjectsIntegTest { + public static class ListAll extends SimpleObjectsIntegTest { - @Test - public void happyCase() throws Exception { + @Test + public void happyCase() throws Exception { - // given - RecreateSimpleObjects fs = new RecreateSimpleObjects(); - fixtureScripts.runFixtureScript(fs, null); - nextTransaction(); + // given + RecreateSimpleObjects fs = new RecreateSimpleObjects(); + fixtureScripts.runFixtureScript(fs, null); + nextTransaction(); - // when - final List all = wrap(simpleObjects).listAll(); + // when + final List all = wrap(simpleObjects).listAll(); - // then - assertThat(all).hasSize(fs.getSimpleObjects().size()); + // then + assertThat(all).hasSize(fs.getSimpleObjects().size()); - SimpleObject simpleObject = wrap(all.get(0)); - assertThat(simpleObject.getName()).isEqualTo(fs.getSimpleObjects().get(0).getName()); - } - - @Test - public void whenNone() throws Exception { - - // given - FixtureScript fs = new SimpleObjectsTearDown(); - fixtureScripts.runFixtureScript(fs, null); - nextTransaction(); - - // when - final List all = wrap(simpleObjects).listAll(); - - // then - assertThat(all).hasSize(0); - } + SimpleObject simpleObject = wrap(all.get(0)); + assertThat(simpleObject.getName()).isEqualTo(fs.getSimpleObjects().get(0).getName()); } - public static class Create extends SimpleObjectsIntegTest { + @Test + public void whenNone() throws Exception { - @Test - public void happyCase() throws Exception { + // given + FixtureScript fs = new SimpleObjectsTearDown(); + fixtureScripts.runFixtureScript(fs, null); + nextTransaction(); - // given - FixtureScript fs = new SimpleObjectsTearDown(); - fixtureScripts.runFixtureScript(fs, null); - nextTransaction(); + // when + final List all = wrap(simpleObjects).listAll(); - // when - wrap(simpleObjects).create("Faz"); - - // then - final List all = wrap(simpleObjects).listAll(); - assertThat(all).hasSize(1); - } - - @Test - public void whenAlreadyExists() throws Exception { - - // given - FixtureScript fs = new SimpleObjectsTearDown(); - fixtureScripts.runFixtureScript(fs, null); - nextTransaction(); - wrap(simpleObjects).create("Faz"); - nextTransaction(); - - // then - expectedExceptions.expectCause(causalChainContains(SQLIntegrityConstraintViolationException.class)); - - // when - wrap(simpleObjects).create("Faz"); - nextTransaction(); - } - - private static Matcher causalChainContains(final Class cls) { - return new TypeSafeMatcher() { - @Override - protected boolean matchesSafely(Throwable item) { - final List causalChain = Throwables.getCausalChain(item); - for (Throwable throwable : causalChain) { - if(cls.isAssignableFrom(throwable.getClass())){ - return true; - } - } - return false; - } - - @Override - public void describeTo(Description description) { - description.appendText("exception with causal chain containing " + cls.getSimpleName()); - } - }; - } + // then + assertThat(all).hasSize(0); } + } + + public static class Create extends SimpleObjectsIntegTest { + + @Test + public void happyCase() throws Exception { + + // given + FixtureScript fs = new SimpleObjectsTearDown(); + fixtureScripts.runFixtureScript(fs, null); + nextTransaction(); + + // when + wrap(simpleObjects).create("Faz"); + + // then + final List all = wrap(simpleObjects).listAll(); + assertThat(all).hasSize(1); + } + + @Test + public void whenAlreadyExists() throws Exception { + + // given + FixtureScript fs = new SimpleObjectsTearDown(); + fixtureScripts.runFixtureScript(fs, null); + nextTransaction(); + wrap(simpleObjects).create("Faz"); + nextTransaction(); + + // then + expectedExceptions.expectCause(causalChainContains(SQLIntegrityConstraintViolationException.class)); + + // when + wrap(simpleObjects).create("Faz"); + nextTransaction(); + } + + private static Matcher causalChainContains(final Class cls) { + return new TypeSafeMatcher() { + @Override + protected boolean matchesSafely(Throwable item) { + final List causalChain = Throwables.getCausalChain(item); + for (Throwable throwable : causalChain) { + if (cls.isAssignableFrom(throwable.getClass())) { + return true; + } + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("exception with causal chain containing " + cls.getSimpleName()); + } + }; + } + } } \ No newline at end of file diff --git a/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java b/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java index c7bbd8c80..a292a7779 100644 --- a/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java +++ b/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java @@ -74,7 +74,7 @@ public class SimpleApplication extends IsisWicketApplication { *

* for demos only, obvious. */ - private final static boolean DEMO_MODE_USING_CREDENTIALS_AS_QUERYARGS = false; + private static final boolean DEMO_MODE_USING_CREDENTIALS_AS_QUERYARGS = false; @Override @@ -116,6 +116,7 @@ public class SimpleApplication extends IsisWicketApplication { servletRequest.getSession().invalidate(); } } catch (Exception e) { + System.out.println(e); } WebRequest request = super.newWebRequest(servletRequest, filterPath); return request; diff --git a/null-object/src/main/java/com/iluwatar/nullobject/NodeImpl.java b/null-object/src/main/java/com/iluwatar/nullobject/NodeImpl.java index 5de258890..4478b9bfa 100644 --- a/null-object/src/main/java/com/iluwatar/nullobject/NodeImpl.java +++ b/null-object/src/main/java/com/iluwatar/nullobject/NodeImpl.java @@ -11,6 +11,9 @@ public class NodeImpl implements Node { private final Node left; private final Node right; + /** + * Constructor + */ public NodeImpl(String name, Node left, Node right) { this.name = name; this.left = left; diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java index 79d7d6345..d85955f0a 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java @@ -5,8 +5,6 @@ import java.util.HashSet; /** * * Generic object pool - * - * @param */ public abstract class ObjectPool { @@ -15,6 +13,9 @@ public abstract class ObjectPool { protected abstract T create(); + /** + * Checkout object from pool + */ public synchronized T checkOut() { if (available.size() <= 0) { available.add(create()); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java index aeefd6b3a..f3923fff5 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java @@ -11,6 +11,9 @@ public class Oliphaunt { private final int id; + /** + * Constructor + */ public Oliphaunt() { id = counter++; try { diff --git a/observer/src/main/java/com/iluwatar/observer/Weather.java b/observer/src/main/java/com/iluwatar/observer/Weather.java index 634953945..4e04143a2 100644 --- a/observer/src/main/java/com/iluwatar/observer/Weather.java +++ b/observer/src/main/java/com/iluwatar/observer/Weather.java @@ -27,6 +27,9 @@ public class Weather { observers.remove(obs); } + /** + * Makes time pass for weather + */ public void timePasses() { WeatherType[] enumValues = WeatherType.values(); currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; diff --git a/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java b/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java index 9d1c6ed07..d503c8421 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/GWeather.java @@ -15,6 +15,9 @@ public class GWeather extends Observable { currentWeather = WeatherType.SUNNY; } + /** + * Makes time pass for weather + */ public void timePasses() { WeatherType[] enumValues = WeatherType.values(); currentWeather = enumValues[(currentWeather.ordinal() + 1) % enumValues.length]; diff --git a/observer/src/main/java/com/iluwatar/observer/generic/Observable.java b/observer/src/main/java/com/iluwatar/observer/generic/Observable.java index f1ad2dca6..f3b3c7dbb 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/Observable.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/Observable.java @@ -22,6 +22,9 @@ public abstract class Observable, O extends Observ this.observers.add(observer); } + /** + * Notify observers + */ @SuppressWarnings("unchecked") public void notifyObservers(A argument) { for (O observer : observers) { diff --git a/observer/src/main/java/com/iluwatar/observer/generic/Observer.java b/observer/src/main/java/com/iluwatar/observer/generic/Observer.java index b01955419..34b9ac359 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/Observer.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/Observer.java @@ -3,10 +3,6 @@ package com.iluwatar.observer.generic; /** * * Observer - * - * @param - * @param - * @param */ public interface Observer, O extends Observer, A> { diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/Consumer.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/Consumer.java index ff06d7d5b..a305c010c 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/Consumer.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/Consumer.java @@ -7,14 +7,17 @@ import com.iluwatar.poison.pill.Message.Headers; */ public class Consumer { - private final MQSubscribePoint queue; + private final MqSubscribePoint queue; private final String name; - public Consumer(String name, MQSubscribePoint queue) { + public Consumer(String name, MqSubscribePoint queue) { this.name = name; this.queue = queue; } + /** + * Consume message + */ public void consume() { while (true) { Message msg; diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/MessageQueue.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/MessageQueue.java index 99231ab51..aa0d3699d 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/MessageQueue.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/MessageQueue.java @@ -3,6 +3,6 @@ package com.iluwatar.poison.pill; /** * Represents abstraction of channel (or pipe) that bounds {@link Producer} and {@link Consumer} */ -public interface MessageQueue extends MQPublishPoint, MQSubscribePoint { +public interface MessageQueue extends MqPublishPoint, MqSubscribePoint { } diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/MQPublishPoint.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/MqPublishPoint.java similarity index 81% rename from poison-pill/src/main/java/com/iluwatar/poison/pill/MQPublishPoint.java rename to poison-pill/src/main/java/com/iluwatar/poison/pill/MqPublishPoint.java index a266d9f4d..74ed43e33 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/MQPublishPoint.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/MqPublishPoint.java @@ -3,7 +3,7 @@ package com.iluwatar.poison.pill; /** * Endpoint to publish {@link Message} to queue */ -public interface MQPublishPoint { +public interface MqPublishPoint { public void put(Message msg) throws InterruptedException; } diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/MQSubscribePoint.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/MqSubscribePoint.java similarity index 80% rename from poison-pill/src/main/java/com/iluwatar/poison/pill/MQSubscribePoint.java rename to poison-pill/src/main/java/com/iluwatar/poison/pill/MqSubscribePoint.java index c093b1412..ed7624116 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/MQSubscribePoint.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/MqSubscribePoint.java @@ -3,7 +3,7 @@ package com.iluwatar.poison.pill; /** * Endpoint to retrieve {@link Message} from queue */ -public interface MQSubscribePoint { +public interface MqSubscribePoint { public Message take() throws InterruptedException; } diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/Producer.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/Producer.java index ecde39e35..5405de869 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/Producer.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/Producer.java @@ -10,16 +10,22 @@ import com.iluwatar.poison.pill.Message.Headers; */ public class Producer { - private final MQPublishPoint queue; + private final MqPublishPoint queue; private final String name; private boolean isStopped; - public Producer(String name, MQPublishPoint queue) { + /** + * Constructor + */ + public Producer(String name, MqPublishPoint queue) { this.name = name; this.queue = queue; this.isStopped = false; } + /** + * Send message to queue + */ public void send(String body) { if (isStopped) { throw new IllegalStateException(String.format( @@ -38,6 +44,9 @@ public class Producer { } } + /** + * Stop system by sending poison pill + */ public void stop() { isStopped = true; try { diff --git a/pom.xml b/pom.xml index 724b058f1..1285c8108 100644 --- a/pom.xml +++ b/pom.xml @@ -244,7 +244,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.15 + 2.17 validate diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java index 599a80407..849c2413c 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java @@ -13,6 +13,9 @@ public class ImmutableStew { data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); } + /** + * Mix the stew + */ public void mix() { System.out.println(String.format( "Mixing the immutable stew we find: %d potatoes, %d carrots, %d meat and %d peppers", diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/Stew.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/Stew.java index 9deb32e16..2efd0b4ee 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/Stew.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/Stew.java @@ -12,6 +12,9 @@ public class Stew { private int numMeat; private int numPeppers; + /** + * Constructor + */ public Stew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { this.numPotatoes = numPotatoes; this.numCarrots = numCarrots; @@ -19,12 +22,18 @@ public class Stew { this.numPeppers = numPeppers; } + /** + * Mix the stew + */ public void mix() { System.out.println(String.format( "Mixing the stew we find: %d potatoes, %d carrots, %d meat and %d peppers", numPotatoes, numCarrots, numMeat, numPeppers)); } + /** + * Taste the stew + */ public void taste() { System.out.println("Tasting the stew"); if (numPotatoes > 0) { diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java index 23d54ccf4..0bd62ada3 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java @@ -12,6 +12,9 @@ public class StewData { private int numMeat; private int numPeppers; + /** + * Constructor + */ public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { this.numPotatoes = numPotatoes; this.numCarrots = numCarrots; diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java index 50d94d92f..63cae9413 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/App.java @@ -5,14 +5,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** - * Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces - * coupling between Producer and Consumer by separating Identification of work with Execution of - * Work. + * Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces coupling between + * Producer and Consumer by separating Identification of work with Execution of Work. *

- * In producer consumer design pattern a shared queue is used to control the flow and this - * separation allows you to code producer and consumer separately. It also addresses the issue of - * different timing require to produce item or consuming item. by using producer consumer pattern - * both Producer and Consumer Thread can work with different speed. + * In producer consumer design pattern a shared queue is used to control the flow and this separation allows you to code + * producer and consumer separately. It also addresses the issue of different timing require to produce item or + * consuming item. by using producer consumer pattern both Producer and Consumer Thread can work with different speed. * */ public class App { @@ -20,7 +18,8 @@ public class App { /** * Program entry point * - * @param args command line args + * @param args + * command line args */ public static void main(String[] args) { @@ -35,7 +34,7 @@ public class App { producer.produce(); } }); - }; + } for (int i = 0; i < 3; i++) { final Consumer consumer = new Consumer("Consumer_" + i, queue); diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java index 8bb3b75b6..ff63ab41b 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Consumer.java @@ -14,6 +14,9 @@ public class Consumer { this.queue = queue; } + /** + * Consume item from the queue + */ public void consume() throws InterruptedException { Item item = queue.take(); diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java index 40e71c607..8b122a5fc 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Producer.java @@ -19,6 +19,9 @@ public class Producer { this.queue = queue; } + /** + * Put item in the queue + */ public void produce() throws InterruptedException { Item item = new Item(name, itemId++); diff --git a/property/src/main/java/com/iluwatar/property/Character.java b/property/src/main/java/com/iluwatar/property/Character.java index 10b8f495d..50e564623 100644 --- a/property/src/main/java/com/iluwatar/property/Character.java +++ b/property/src/main/java/com/iluwatar/property/Character.java @@ -18,6 +18,9 @@ public class Character implements Prototype { private String name; private Type type; + /** + * Constructor + */ public Character() { this.prototype = new Prototype() { // Null-value object @Override @@ -43,6 +46,9 @@ public class Character implements Prototype { this.prototype = prototype; } + /** + * Constructor + */ public Character(String name, Character prototype) { this.name = name; this.type = prototype.type; diff --git a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java index 4c5a60bcd..85792104d 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java +++ b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java @@ -11,12 +11,18 @@ public class HeroFactoryImpl implements HeroFactory { private Warlord warlord; private Beast beast; + /** + * Constructor + */ public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { this.mage = mage; this.warlord = warlord; this.beast = beast; } + /** + * Create mage + */ public Mage createMage() { try { return mage.clone(); @@ -25,6 +31,9 @@ public class HeroFactoryImpl implements HeroFactory { } } + /** + * Create warlord + */ public Warlord createWarlord() { try { return warlord.clone(); @@ -33,6 +42,9 @@ public class HeroFactoryImpl implements HeroFactory { } } + /** + * Create beast + */ public Beast createBeast() { try { return beast.clone(); diff --git a/proxy/src/main/java/com/iluwatar/proxy/App.java b/proxy/src/main/java/com/iluwatar/proxy/App.java index 25a903e41..837424f28 100644 --- a/proxy/src/main/java/com/iluwatar/proxy/App.java +++ b/proxy/src/main/java/com/iluwatar/proxy/App.java @@ -18,6 +18,9 @@ package com.iluwatar.proxy; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { WizardTowerProxy tower = new WizardTowerProxy(); diff --git a/publish-subscribe/src/main/java/com/iluwatar/publish/subscribe/App.java b/publish-subscribe/src/main/java/com/iluwatar/publish/subscribe/App.java index 30f982ed1..f80dd1ad1 100644 --- a/publish-subscribe/src/main/java/com/iluwatar/publish/subscribe/App.java +++ b/publish-subscribe/src/main/java/com/iluwatar/publish/subscribe/App.java @@ -28,10 +28,6 @@ public class App { /** * Program entry point - * - * @param args - * command line args - * @throws Exception */ public static void main(String[] args) throws Exception { CamelContext context = new DefaultCamelContext(); diff --git a/reactor/src/main/java/com/iluwatar/reactor/app/App.java b/reactor/src/main/java/com/iluwatar/reactor/app/App.java index 2c49d9001..d074c9b19 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/app/App.java +++ b/reactor/src/main/java/com/iluwatar/reactor/app/App.java @@ -80,8 +80,6 @@ public class App { /** * App entry. - * - * @throws IOException */ public static void main(String[] args) throws IOException { new App(new ThreadPoolDispatcher(2)).start(); diff --git a/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java b/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java index ee25b0be0..13cdd70e1 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java +++ b/reactor/src/main/java/com/iluwatar/reactor/app/AppClient.java @@ -37,10 +37,10 @@ public class AppClient { * @throws IOException if any I/O error occurs. */ public void start() throws IOException { - service.execute(new TCPLoggingClient("Client 1", 6666)); - service.execute(new TCPLoggingClient("Client 2", 6667)); - service.execute(new UDPLoggingClient("Client 3", 6668)); - service.execute(new UDPLoggingClient("Client 4", 6668)); + service.execute(new TcpLoggingClient("Client 1", 6666)); + service.execute(new TcpLoggingClient("Client 2", 6667)); + service.execute(new UdpLoggingClient("Client 3", 6668)); + service.execute(new UdpLoggingClient("Client 4", 6668)); } /** @@ -69,7 +69,7 @@ public class AppClient { /** * A logging client that sends requests to Reactor on TCP socket. */ - static class TCPLoggingClient implements Runnable { + static class TcpLoggingClient implements Runnable { private final int serverPort; private final String clientName; @@ -80,7 +80,7 @@ public class AppClient { * @param clientName the name of the client to be sent in logging requests. * @param port the port on which client will send logging requests. */ - public TCPLoggingClient(String clientName, int serverPort) { + public TcpLoggingClient(String clientName, int serverPort) { this.clientName = clientName; this.serverPort = serverPort; } @@ -118,7 +118,7 @@ public class AppClient { /** * A logging client that sends requests to Reactor on UDP socket. */ - static class UDPLoggingClient implements Runnable { + static class UdpLoggingClient implements Runnable { private final String clientName; private final InetSocketAddress remoteAddress; @@ -129,7 +129,7 @@ public class AppClient { * @param port the port on which client will send logging requests. * @throws UnknownHostException if localhost is unknown */ - public UDPLoggingClient(String clientName, int port) throws UnknownHostException { + public UdpLoggingClient(String clientName, int port) throws UnknownHostException { this.clientName = clientName; this.remoteAddress = new InetSocketAddress(InetAddress.getLocalHost(), port); } diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/AbstractNioChannel.java b/reactor/src/main/java/com/iluwatar/reactor/framework/AbstractNioChannel.java index df08426d0..cd1318c89 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/AbstractNioChannel.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/AbstractNioChannel.java @@ -131,6 +131,7 @@ public abstract class AbstractNioChannel { * channel.write(buffer, key); * } * + * * * @param data the data to be written on underlying channel. * @param key the key which is writable. diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java index 16c13e5f9..271a6975d 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java @@ -14,40 +14,41 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** - * This class acts as Synchronous Event De-multiplexer and Initiation Dispatcher of Reactor pattern. - * Multiple handles i.e. {@link AbstractNioChannel}s can be registered to the reactor and it blocks - * for events from all these handles. Whenever an event occurs on any of the registered handles, it - * synchronously de-multiplexes the event which can be any of read, write or accept, and dispatches - * the event to the appropriate {@link ChannelHandler} using the {@link Dispatcher}. + * This class acts as Synchronous Event De-multiplexer and Initiation Dispatcher of Reactor pattern. Multiple handles + * i.e. {@link AbstractNioChannel}s can be registered to the reactor and it blocks for events from all these handles. + * Whenever an event occurs on any of the registered handles, it synchronously de-multiplexes the event which can be any + * of read, write or accept, and dispatches the event to the appropriate {@link ChannelHandler} using the + * {@link Dispatcher}. * *

- * Implementation: A NIO reactor runs in its own thread when it is started using {@link #start()} - * method. {@link NioReactor} uses {@link Selector} for realizing Synchronous Event De-multiplexing. + * Implementation: A NIO reactor runs in its own thread when it is started using {@link #start()} method. + * {@link NioReactor} uses {@link Selector} for realizing Synchronous Event De-multiplexing. * *

- * NOTE: This is one of the ways to implement NIO reactor and it does not take care of all possible - * edge cases which are required in a real application. This implementation is meant to demonstrate - * the fundamental concepts that lie behind Reactor pattern. + * NOTE: This is one of the ways to implement NIO reactor and it does not take care of all possible edge cases which are + * required in a real application. This implementation is meant to demonstrate the fundamental concepts that lie behind + * Reactor pattern. */ public class NioReactor { private final Selector selector; private final Dispatcher dispatcher; /** - * All the work of altering the SelectionKey operations and Selector operations are performed in - * the context of main event loop of reactor. So when any channel needs to change its readability - * or writability, a new command is added in the command queue and then the event loop picks up - * the command and executes it in next iteration. + * All the work of altering the SelectionKey operations and Selector operations are performed in the context of main + * event loop of reactor. So when any channel needs to change its readability or writability, a new command is added + * in the command queue and then the event loop picks up the command and executes it in next iteration. */ private final Queue pendingCommands = new ConcurrentLinkedQueue<>(); private final ExecutorService reactorMain = Executors.newSingleThreadExecutor(); /** - * Creates a reactor which will use provided {@code dispatcher} to dispatch events. The - * application can provide various implementations of dispatcher which suits its needs. + * Creates a reactor which will use provided {@code dispatcher} to dispatch events. The application can provide + * various implementations of dispatcher which suits its needs. * - * @param dispatcher a non-null dispatcher used to dispatch events on registered channels. - * @throws IOException if any I/O error occurs. + * @param dispatcher + * a non-null dispatcher used to dispatch events on registered channels. + * @throws IOException + * if any I/O error occurs. */ public NioReactor(Dispatcher dispatcher) throws IOException { this.dispatcher = dispatcher; @@ -57,7 +58,8 @@ public class NioReactor { /** * Starts the reactor event loop in a new thread. * - * @throws IOException if any I/O error occurs. + * @throws IOException + * if any I/O error occurs. */ public void start() throws IOException { reactorMain.execute(() -> { @@ -73,8 +75,10 @@ public class NioReactor { /** * Stops the reactor and related resources such as dispatcher. * - * @throws InterruptedException if interrupted while stopping the reactor. - * @throws IOException if any I/O error occurs. + * @throws InterruptedException + * if interrupted while stopping the reactor. + * @throws IOException + * if any I/O error occurs. */ public void stop() throws InterruptedException, IOException { reactorMain.shutdownNow(); @@ -84,15 +88,15 @@ public class NioReactor { } /** - * Registers a new channel (handle) with this reactor. Reactor will start waiting for events on - * this channel and notify of any events. While registering the channel the reactor uses - * {@link AbstractNioChannel#getInterestedOps()} to know about the interested operation of this - * channel. + * Registers a new channel (handle) with this reactor. Reactor will start waiting for events on this channel and + * notify of any events. While registering the channel the reactor uses {@link AbstractNioChannel#getInterestedOps()} + * to know about the interested operation of this channel. * - * @param channel a new channel on which reactor will wait for events. The channel must be bound - * prior to being registered. + * @param channel + * a new channel on which reactor will wait for events. The channel must be bound prior to being registered. * @return this - * @throws IOException if any I/O error occurs. + * @throws IOException + * if any I/O error occurs. */ public NioReactor registerChannel(AbstractNioChannel channel) throws IOException { SelectionKey key = channel.getJavaChannel().register(selector, channel.getInterestedOps()); @@ -113,8 +117,8 @@ public class NioReactor { processPendingCommands(); /* - * Synchronous event de-multiplexing happens here, this is blocking call which returns when it - * is possible to initiate non-blocking operation on any of the registered channels. + * Synchronous event de-multiplexing happens here, this is blocking call which returns when it is possible to + * initiate non-blocking operation on any of the registered channels. */ selector.select(); @@ -147,8 +151,8 @@ public class NioReactor { } /* - * Initiation dispatcher logic, it checks the type of event and notifier application specific - * event handler to handle the event. + * Initiation dispatcher logic, it checks the type of event and notifier application specific event handler to handle + * the event. */ private void processKey(SelectionKey key) throws IOException { if (key.isAcceptable()) { @@ -196,14 +200,15 @@ public class NioReactor { } /** - * Queues the change of operations request of a channel, which will change the interested - * operations of the channel sometime in future. + * Queues the change of operations request of a channel, which will change the interested operations of the channel + * sometime in future. *

- * This is a non-blocking method and does not guarantee that the operations have changed when this - * method returns. + * This is a non-blocking method and does not guarantee that the operations have changed when this method returns. * - * @param key the key for which operations have to be changed. - * @param interestedOps the new interest operations. + * @param key + * the key for which operations have to be changed. + * @param interestedOps + * the new interest operations. */ public void changeOps(SelectionKey key, int interestedOps) { pendingCommands.add(new ChangeKeyOpsCommand(key, interestedOps)); diff --git a/repository/src/main/java/com/iluwatar/repository/AppConfig.java b/repository/src/main/java/com/iluwatar/repository/AppConfig.java index cca09d8aa..62b9a4c04 100644 --- a/repository/src/main/java/com/iluwatar/repository/AppConfig.java +++ b/repository/src/main/java/com/iluwatar/repository/AppConfig.java @@ -39,8 +39,6 @@ public class AppConfig { /** * Factory to create a especific instance of Entity Manager - * - * @return */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { @@ -55,8 +53,6 @@ public class AppConfig { /** * Properties for Jpa - * - * @return */ private Properties jpaProperties() { Properties properties = new Properties(); @@ -65,6 +61,9 @@ public class AppConfig { return properties; } + /** + * Get transaction manager + */ @Bean public JpaTransactionManager transactionManager() throws SQLException { JpaTransactionManager transactionManager = new JpaTransactionManager(); diff --git a/repository/src/main/java/com/iluwatar/repository/Person.java b/repository/src/main/java/com/iluwatar/repository/Person.java index ca4013b54..04d65a6d0 100644 --- a/repository/src/main/java/com/iluwatar/repository/Person.java +++ b/repository/src/main/java/com/iluwatar/repository/Person.java @@ -23,6 +23,9 @@ public class Person { public Person() { } + /** + * Constructor + */ public Person(String name, String surname, int age) { this.name = name; this.surname = surname; @@ -80,30 +83,40 @@ public class Person { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } Person other = (Person) obj; - if (age != other.age) + if (age != other.age) { return false; + } if (id == null) { - if (other.id != null) + if (other.id != null) { return false; - } else if (!id.equals(other.id)) + } + } else if (!id.equals(other.id)) { return false; + } if (name == null) { - if (other.name != null) + if (other.name != null) { return false; - } else if (!name.equals(other.name)) + } + } else if (!name.equals(other.name)) { return false; + } if (surname == null) { - if (other.surname != null) + if (other.surname != null) { return false; - } else if (!surname.equals(other.surname)) + } + } else if (!surname.equals(other.surname)) { return false; + } return true; } diff --git a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java index ce9842dff..fa96f3ca6 100644 --- a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java +++ b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java @@ -32,6 +32,10 @@ public class PersonSpecifications { } + /** + * Name specification + * + */ public static class NameEqualSpec implements Specification { public String name; @@ -40,6 +44,9 @@ public class PersonSpecifications { this.name = name; } + /** + * Get predicate + */ public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { return cb.equal(root.get("name"), this.name); diff --git a/repository/src/main/resources/META-INF/persistence.xml b/repository/src/main/resources/META-INF/persistence.xml index 0aded0dbd..00767fbc2 100644 --- a/repository/src/main/resources/META-INF/persistence.xml +++ b/repository/src/main/resources/META-INF/persistence.xml @@ -1,8 +1,8 @@ + xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> - + diff --git a/repository/src/main/resources/applicationContext.xml b/repository/src/main/resources/applicationContext.xml index 9322c9f64..ed03aba0a 100644 --- a/repository/src/main/resources/applicationContext.xml +++ b/repository/src/main/resources/applicationContext.xml @@ -1,39 +1,37 @@ - + - - - - - + - - - - - - + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java index 6f8746aa6..682d2021f 100644 --- a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java @@ -90,8 +90,8 @@ public class AnnotationBasedRepositoryTest { assertEquals(3, persons.size()); assertTrue(persons.stream().allMatch((item) -> { - return item.getAge() > 20 && item.getAge() < 40; - })); + return item.getAge() > 20 && item.getAge() < 40; + })); } @Test diff --git a/repository/src/test/java/com/iluwatar/repository/AppConfigTest.java b/repository/src/test/java/com/iluwatar/repository/AppConfigTest.java index 49e684bf1..17393f2ff 100644 --- a/repository/src/test/java/com/iluwatar/repository/AppConfigTest.java +++ b/repository/src/test/java/com/iluwatar/repository/AppConfigTest.java @@ -1,6 +1,7 @@ package com.iluwatar.repository; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.sql.ResultSet; import java.sql.SQLException; @@ -36,8 +37,6 @@ public class AppConfigTest { /** * Test for correct query execution - * - * @throws SQLException */ @Test @Transactional diff --git a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java index 3d6708815..9eb6b4723 100644 --- a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java @@ -88,8 +88,8 @@ public class RepositoryTest { assertEquals(3, persons.size()); assertTrue(persons.stream().allMatch((item) -> { - return item.getAge() > 20 && item.getAge() < 40; - })); + return item.getAge() > 20 && item.getAge() < 40; + })); } @Test diff --git a/resource-acquisition-is-initialization/src/main/java/com/iluwatar/resource/acquisition/is/initialization/App.java b/resource-acquisition-is-initialization/src/main/java/com/iluwatar/resource/acquisition/is/initialization/App.java index 32cd3792e..f734432af 100644 --- a/resource-acquisition-is-initialization/src/main/java/com/iluwatar/resource/acquisition/is/initialization/App.java +++ b/resource-acquisition-is-initialization/src/main/java/com/iluwatar/resource/acquisition/is/initialization/App.java @@ -24,9 +24,6 @@ public class App { /** * Program entry point - * - * @param args command line args - * @throws Exception */ public static void main(String[] args) throws Exception { diff --git a/servant/src/main/java/com/iluwatar/servant/App.java b/servant/src/main/java/com/iluwatar/servant/App.java index 42babbc1d..cb5a63fa5 100644 --- a/servant/src/main/java/com/iluwatar/servant/App.java +++ b/servant/src/main/java/com/iluwatar/servant/App.java @@ -18,15 +18,13 @@ public class App { /** * Program entry point - * - * @param args */ public static void main(String[] args) { scenario(jenkins, 1); scenario(travis, 0); } - /* + /** * Can add a List with enum Actions for variable scenarios */ public static void scenario(Servant servant, int compliment) { @@ -44,16 +42,18 @@ public class App { servant.giveWine(k); servant.giveWine(q); // compliment - servant.GiveCompliments(guests.get(compliment)); + servant.giveCompliments(guests.get(compliment)); // outcome of the night - for (Royalty r : guests) + for (Royalty r : guests) { r.changeMood(); + } // check your luck - if (servant.checkIfYouWillBeHanged(guests)) + if (servant.checkIfYouWillBeHanged(guests)) { System.out.println(servant.name + " will live another day"); - else + } else { System.out.println("Poor " + servant.name + ". His days are numbered"); + } } } diff --git a/servant/src/main/java/com/iluwatar/servant/King.java b/servant/src/main/java/com/iluwatar/servant/King.java index 5e931c149..ab99252ad 100644 --- a/servant/src/main/java/com/iluwatar/servant/King.java +++ b/servant/src/main/java/com/iluwatar/servant/King.java @@ -28,10 +28,12 @@ public class King implements Royalty { @Override public void changeMood() { - if (!isHungry && isDrunk) + if (!isHungry && isDrunk) { isHappy = true; - if (complimentReceived) + } + if (complimentReceived) { isHappy = false; + } } @Override diff --git a/servant/src/main/java/com/iluwatar/servant/Queen.java b/servant/src/main/java/com/iluwatar/servant/Queen.java index db5446d34..cc33ab470 100644 --- a/servant/src/main/java/com/iluwatar/servant/Queen.java +++ b/servant/src/main/java/com/iluwatar/servant/Queen.java @@ -29,8 +29,9 @@ public class Queen implements Royalty { @Override public void changeMood() { - if (complimentReceived && isFlirty && isDrunk) + if (complimentReceived && isFlirty && isDrunk) { isHappy = true; + } } @Override diff --git a/servant/src/main/java/com/iluwatar/servant/Servant.java b/servant/src/main/java/com/iluwatar/servant/Servant.java index 987bf8791..dbb623331 100644 --- a/servant/src/main/java/com/iluwatar/servant/Servant.java +++ b/servant/src/main/java/com/iluwatar/servant/Servant.java @@ -11,6 +11,9 @@ public class Servant { public String name; + /** + * Constructor + */ public Servant(String name) { this.name = name; } @@ -23,15 +26,20 @@ public class Servant { r.getDrink(); } - public void GiveCompliments(Royalty r) { + public void giveCompliments(Royalty r) { r.receiveCompliments(); } + /** + * Check if we will be hanged + */ public boolean checkIfYouWillBeHanged(ArrayList tableGuests) { boolean anotherDay = true; - for (Royalty r : tableGuests) - if (!r.getMood()) + for (Royalty r : tableGuests) { + if (!r.getMood()) { anotherDay = false; + } + } return anotherDay; } diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java b/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java index a7053165d..ab0d3f9a0 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java @@ -47,6 +47,9 @@ public class App { queryData(); } + /** + * Initialize data + */ public static void initData() { // spells Spell spell1 = new Spell("Ice dart"); @@ -149,6 +152,9 @@ public class App { wizardDao.merge(wizard4); } + /** + * Query the data + */ public static void queryData() { MagicService service = new MagicServiceImpl(new WizardDaoImpl(), new SpellbookDaoImpl(), new SpellDaoImpl()); diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/common/DaoBaseImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/common/DaoBaseImpl.java index eae9286fa..2665ff858 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/common/DaoBaseImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/common/DaoBaseImpl.java @@ -39,8 +39,9 @@ public abstract class DaoBaseImpl implements Dao { result = (E) criteria.uniqueResult(); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); @@ -57,8 +58,9 @@ public abstract class DaoBaseImpl implements Dao { session.persist(entity); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); @@ -75,8 +77,9 @@ public abstract class DaoBaseImpl implements Dao { result = (E) session.merge(entity); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); @@ -93,8 +96,9 @@ public abstract class DaoBaseImpl implements Dao { session.delete(entity); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); @@ -111,8 +115,9 @@ public abstract class DaoBaseImpl implements Dao { Criteria criteria = session.createCriteria(persistentClass); result = criteria.list(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/hibernate/HibernateUtil.java b/service-layer/src/main/java/com/iluwatar/servicelayer/hibernate/HibernateUtil.java index 9d1aec488..fce6fb873 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/hibernate/HibernateUtil.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/hibernate/HibernateUtil.java @@ -14,11 +14,11 @@ import com.iluwatar.servicelayer.wizard.Wizard; */ public class HibernateUtil { - private static final SessionFactory sessionFactory; + private static final SessionFactory SESSION_FACTORY; static { try { - sessionFactory = + SESSION_FACTORY = new Configuration().addAnnotatedClass(Wizard.class).addAnnotatedClass(Spellbook.class) .addAnnotatedClass(Spell.class) .setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect") @@ -33,6 +33,6 @@ public class HibernateUtil { } public static SessionFactory getSessionFactory() { - return sessionFactory; + return SESSION_FACTORY; } } diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java index f46f55184..cda3fe58d 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java @@ -21,6 +21,9 @@ public class MagicServiceImpl implements MagicService { private SpellbookDao spellbookDao; private SpellDao spellDao; + /** + * Constructor + */ public MagicServiceImpl(WizardDao wizardDao, SpellbookDao spellbookDao, SpellDao spellDao) { this.wizardDao = wizardDao; this.spellbookDao = spellbookDao; diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/spell/SpellDaoImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/spell/SpellDaoImpl.java index f5f017625..66d06448b 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/spell/SpellDaoImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/spell/SpellDaoImpl.java @@ -27,8 +27,9 @@ public class SpellDaoImpl extends DaoBaseImpl implements SpellDao { result.getSpellbook().getWizards().size(); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/spellbook/SpellbookDaoImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/spellbook/SpellbookDaoImpl.java index 1de82d4a9..842764056 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/spellbook/SpellbookDaoImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/spellbook/SpellbookDaoImpl.java @@ -28,8 +28,9 @@ public class SpellbookDaoImpl extends DaoBaseImpl implements Spellboo result.getWizards().size(); tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/wizard/WizardDaoImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/wizard/WizardDaoImpl.java index ad89dd28a..9ff36edef 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/wizard/WizardDaoImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/wizard/WizardDaoImpl.java @@ -30,8 +30,9 @@ public class WizardDaoImpl extends DaoBaseImpl implements WizardDao { } tx.commit(); } catch (Exception e) { - if (tx != null) + if (tx != null) { tx.rollback(); + } throw e; } finally { session.close(); diff --git a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceImpl.java b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceImpl.java index f2d338cdc..f2dd31221 100644 --- a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceImpl.java +++ b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceImpl.java @@ -12,6 +12,9 @@ public class ServiceImpl implements Service { private final String serviceName; private final int id; + /** + * Constructor + */ public ServiceImpl(String serviceName) { // set the service name this.serviceName = serviceName; diff --git a/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java index 585b11e61..f8b7e170f 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/IvoryTower.java @@ -8,7 +8,7 @@ public final class IvoryTower { /** * Static to class instance of the class. */ - private static final IvoryTower instance = new IvoryTower(); + private static final IvoryTower INSTANCE = new IvoryTower(); /** * Private constructor so nobody can instantiate the class. @@ -21,6 +21,6 @@ public final class IvoryTower { * @return instance of the singleton. */ public static IvoryTower getInstance() { - return instance; + return INSTANCE; } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java index 1aca15b30..ab39a652d 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java @@ -11,14 +11,14 @@ package com.iluwatar.singleton; */ public class ThreadSafeDoubleCheckLocking { - private static volatile ThreadSafeDoubleCheckLocking INSTANCE; + private static volatile ThreadSafeDoubleCheckLocking instance; /** * private constructor to prevent client from instantiating. */ private ThreadSafeDoubleCheckLocking() { // to prevent instantiating by Reflection call - if (INSTANCE != null) { + if (instance != null) { throw new IllegalStateException("Already initialized."); } } @@ -31,12 +31,12 @@ public class ThreadSafeDoubleCheckLocking { public static ThreadSafeDoubleCheckLocking getInstance() { // local variable increases performance by 25 percent // Joshua Bloch "Effective Java, Second Edition", p. 283-284 - ThreadSafeDoubleCheckLocking result = INSTANCE; + ThreadSafeDoubleCheckLocking result = instance; if (result == null) { synchronized (ThreadSafeDoubleCheckLocking.class) { - result = INSTANCE; + result = instance; if (result == null) { - INSTANCE = result = new ThreadSafeDoubleCheckLocking(); + instance = result = new ThreadSafeDoubleCheckLocking(); } } } diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java index 98281b4c8..e67922016 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeLazyLoadedIvoryTower.java @@ -16,7 +16,7 @@ public class ThreadSafeLazyLoadedIvoryTower { /** * The instance gets created only when it is called for first time. Lazy-loading */ - public synchronized static ThreadSafeLazyLoadedIvoryTower getInstance() { + public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() { if (instance == null) { instance = new ThreadSafeLazyLoadedIvoryTower(); diff --git a/singleton/src/test/java/com/iluwatar/singleton/LazyLoadedSingletonThreadSafetyTest.java b/singleton/src/test/java/com/iluwatar/singleton/LazyLoadedSingletonThreadSafetyTest.java index 3afc1bf14..24cd7cf4b 100644 --- a/singleton/src/test/java/com/iluwatar/singleton/LazyLoadedSingletonThreadSafetyTest.java +++ b/singleton/src/test/java/com/iluwatar/singleton/LazyLoadedSingletonThreadSafetyTest.java @@ -1,13 +1,17 @@ package com.iluwatar.singleton; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; -import static org.junit.Assert.assertEquals; +import org.junit.Test; /** * This class provides several test case that test singleton construction. @@ -29,7 +33,7 @@ public class LazyLoadedSingletonThreadSafetyTest { } @Test - public void test_MultipleCallsReturnTheSameObjectInSameThread() { + public void testMultipleCallsReturnTheSameObjectInSameThread() { // Create several instances in the same calling thread ThreadSafeLazyLoadedIvoryTower instance1 = ThreadSafeLazyLoadedIvoryTower.getInstance(); ThreadSafeLazyLoadedIvoryTower instance2 = ThreadSafeLazyLoadedIvoryTower.getInstance(); @@ -42,9 +46,10 @@ public class LazyLoadedSingletonThreadSafetyTest { } @Test - public void test_MultipleCallsReturnTheSameObjectInDifferentThreads() + public void testMultipleCallsReturnTheSameObjectInDifferentThreads() throws InterruptedException, ExecutionException { - {// create several threads and inside each callable instantiate the singleton class + { + // create several threads and inside each callable instantiate the singleton class ExecutorService executorService = Executors.newSingleThreadExecutor(); List> threadList = new ArrayList<>(); @@ -63,7 +68,8 @@ public class LazyLoadedSingletonThreadSafetyTest { // tidy up the executor executorService.shutdown(); } - {// now check the contents that were added to threadObjects by each thread + { + // now check the contents that were added to threadObjects by each thread assertEquals(NUM_THREADS, threadObjects.size()); assertEquals(threadObjects.get(0), threadObjects.get(1)); assertEquals(threadObjects.get(1), threadObjects.get(2)); diff --git a/specification/src/main/java/com/iluwatar/specification/app/App.java b/specification/src/main/java/com/iluwatar/specification/app/App.java index d755d6c2e..373a24f92 100644 --- a/specification/src/main/java/com/iluwatar/specification/app/App.java +++ b/specification/src/main/java/com/iluwatar/specification/app/App.java @@ -31,6 +31,9 @@ import com.iluwatar.specification.selector.MovementSelector; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { // initialize creatures list List creatures = diff --git a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java index 2ec3ccf55..f02befb73 100644 --- a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java +++ b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java @@ -16,6 +16,9 @@ public abstract class AbstractCreature implements Creature { private Movement movement; private Color color; + /** + * Constructor + */ public AbstractCreature(String name, Size size, Movement movement, Color color) { this.name = name; this.size = size; diff --git a/state/src/main/java/com/iluwatar/state/App.java b/state/src/main/java/com/iluwatar/state/App.java index 2013466e0..63b59ad59 100644 --- a/state/src/main/java/com/iluwatar/state/App.java +++ b/state/src/main/java/com/iluwatar/state/App.java @@ -13,6 +13,9 @@ package com.iluwatar.state; */ public class App { + /** + * Program entry point + */ public static void main(String[] args) { Mammoth mammoth = new Mammoth(); diff --git a/state/src/main/java/com/iluwatar/state/Mammoth.java b/state/src/main/java/com/iluwatar/state/Mammoth.java index 8269ecb3d..92f4d7188 100644 --- a/state/src/main/java/com/iluwatar/state/Mammoth.java +++ b/state/src/main/java/com/iluwatar/state/Mammoth.java @@ -13,6 +13,9 @@ public class Mammoth { state = new PeacefulState(this); } + /** + * Makes time pass for the mammoth + */ public void timePasses() { if (state.getClass().equals(PeacefulState.class)) { changeStateTo(new AngryState(this)); diff --git a/step-builder/src/main/java/com/iluwatar/stepbuilder/App.java b/step-builder/src/main/java/com/iluwatar/stepbuilder/App.java index 3bf7b9a68..a839cd49e 100644 --- a/step-builder/src/main/java/com/iluwatar/stepbuilder/App.java +++ b/step-builder/src/main/java/com/iluwatar/stepbuilder/App.java @@ -11,7 +11,7 @@ package com.iluwatar.stepbuilder; * methods available, NO build method until is the right time to build the object. * *

- * Implementation
+ * Implementation *