Merge pull request #515 from dbryla/master

#502 Added logging framework to repository
This commit is contained in:
Ilkka Seppälä 2016-11-18 20:47:17 +02:00 committed by GitHub
commit 68ec24c62e
215 changed files with 2927 additions and 2450 deletions

30
.gitignore vendored
View File

@ -1,19 +1,19 @@
target
.metadata
.settings
.classpath
.project
*.class
# Package Files #
*.jar
*.war
*.ear
.idea
*.iml
*.swp
target
.metadata
.settings
.classpath
.project
*.class
# Package Files #
*.jar
*.war
*.ear
.idea
*.iml
*.swp
datanucleus.log
/bin/
/bin/
/bin/
data-mapper/src/main/resources/log4j.xml
*.log
data-mapper/src/main/resources/log4j.xml

View File

@ -27,6 +27,8 @@ import com.iluwatar.abstractdocument.domain.HasModel;
import com.iluwatar.abstractdocument.domain.HasParts;
import com.iluwatar.abstractdocument.domain.HasPrice;
import com.iluwatar.abstractdocument.domain.HasType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.HashMap;
@ -44,11 +46,13 @@ import java.util.Map;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Executes the App
*/
public App() {
System.out.println("Constructing parts and car");
LOGGER.info("Constructing parts and car");
Map<String, Object> carProperties = new HashMap<>();
carProperties.put(HasModel.PROPERTY, "300SL");
@ -68,12 +72,11 @@ public class App {
Car car = new Car(carProperties);
System.out.println("Here is our car:");
System.out.println("-> model: " + car.getModel().get());
System.out.println("-> price: " + car.getPrice().get());
System.out.println("-> parts: ");
car.getParts().forEach(p -> System.out
.println("\t" + p.getType().get() + "/" + p.getModel().get() + "/" + p.getPrice().get()));
LOGGER.info("Here is our car:");
LOGGER.info("-> model: {}", car.getModel().get());
LOGGER.info("-> price: {}", car.getPrice().get());
LOGGER.info("-> parts: ");
car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", p.getType().get(), p.getModel().get(), p.getPrice().get()));
}
/**

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.abstractfactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
@ -39,6 +42,8 @@ package com.iluwatar.abstractfactory;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private King king;
private Castle castle;
private Army army;
@ -98,17 +103,17 @@ public class App {
App app = new App();
System.out.println("Elf Kingdom");
LOGGER.info("Elf Kingdom");
app.createKingdom(new ElfKingdomFactory());
System.out.println(app.getArmy().getDescription());
System.out.println(app.getCastle().getDescription());
System.out.println(app.getKing().getDescription());
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
System.out.println("\nOrc Kingdom");
LOGGER.info("Orc Kingdom");
app.createKingdom(new OrcKingdomFactory());
System.out.println(app.getArmy().getDescription());
System.out.println(app.getCastle().getDescription());
System.out.println(app.getKing().getDescription());
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.adapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
@ -33,6 +36,8 @@ package com.iluwatar.adapter;
*/
public class BattleFishingBoat implements BattleShip {
private static final Logger LOGGER = LoggerFactory.getLogger(BattleFishingBoat.class);
private FishingBoat boat;
public BattleFishingBoat() {
@ -41,7 +46,7 @@ public class BattleFishingBoat implements BattleShip {
@Override
public void fire() {
System.out.println("fire!");
LOGGER.info("fire!");
}
@Override

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.adapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Device class (adaptee in the pattern). We want to reuse this class
@ -29,12 +32,14 @@ package com.iluwatar.adapter;
*/
public class FishingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
public void sail() {
System.out.println("The Boat is moving to that place");
LOGGER.info("The Boat is moving to that place");
}
public void fish() {
System.out.println("fishing ...");
LOGGER.info("fishing ...");
}
}

View File

@ -27,6 +27,8 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
@ -37,6 +39,8 @@ import java.io.IOException;
@Component
public class ProductInformationClientImpl implements ProductInformationClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInformationClientImpl.class);
@Override
public String getProductTitle() {
String response = null;
@ -46,7 +50,7 @@ public class ProductInformationClientImpl implements ProductInformationClient {
response = EntityUtils.toString(httpResponse.getEntity());
}
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Exception caught.", e);
}
return response;
}

View File

@ -27,6 +27,8 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException;
@ -37,6 +39,8 @@ import java.io.IOException;
@Component
public class ProductInventoryClientImpl implements ProductInventoryClient {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductInventoryClientImpl.class);
@Override
public int getProductInventories() {
String response = "0";
@ -46,7 +50,7 @@ public class ProductInventoryClientImpl implements ProductInventoryClient {
response = EntityUtils.toString(httpResponse.getEntity());
}
} catch (IOException e) {
e.printStackTrace();
LOGGER.error("Exception caught.", e);
}
return Integer.parseInt(response);
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.async.method.invocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Callable;
/**
@ -54,6 +57,8 @@ import java.util.concurrent.Callable;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*/
@ -120,6 +125,6 @@ public class App {
}
private static void log(String msg) {
System.out.println(String.format("[%1$-10s] - %2$s", Thread.currentThread().getName(), msg));
LOGGER.info(msg);
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Excalibur
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/
public class Excalibur extends BlindingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class);
@Override
public void wieldImp() {
System.out.println("wielding Excalibur");
LOGGER.info("wielding Excalibur");
}
@Override
public void swingImp() {
System.out.println("swinging Excalibur");
LOGGER.info("swinging Excalibur");
}
@Override
public void unwieldImp() {
System.out.println("unwielding Excalibur");
LOGGER.info("unwielding Excalibur");
}
@Override
public void blindImp() {
System.out.println("bright light streams from Excalibur blinding the enemy");
LOGGER.info("bright light streams from Excalibur blinding the enemy");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Mjollnir
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/
public class Mjollnir extends FlyingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class);
@Override
public void wieldImp() {
System.out.println("wielding Mjollnir");
LOGGER.info("wielding Mjollnir");
}
@Override
public void swingImp() {
System.out.println("swinging Mjollnir");
LOGGER.info("swinging Mjollnir");
}
@Override
public void unwieldImp() {
System.out.println("unwielding Mjollnir");
LOGGER.info("unwielding Mjollnir");
}
@Override
public void flyImp() {
System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand");
LOGGER.info("Mjollnir hits the enemy in the air and returns back to the owner's hand");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Stormbringer
@ -29,23 +32,25 @@ package com.iluwatar.bridge;
*/
public class Stormbringer extends SoulEatingMagicWeaponImpl {
private static final Logger LOGGER = LoggerFactory.getLogger(Stormbringer.class);
@Override
public void wieldImp() {
System.out.println("wielding Stormbringer");
LOGGER.info("wielding Stormbringer");
}
@Override
public void swingImp() {
System.out.println("swinging Stormbringer");
LOGGER.info("swinging Stormbringer");
}
@Override
public void unwieldImp() {
System.out.println("unwielding Stormbringer");
LOGGER.info("unwielding Stormbringer");
}
@Override
public void eatSoulImp() {
System.out.println("Stormbringer devours the enemy's soul");
LOGGER.info("Stormbringer devours the enemy's soul");
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.builder;
import com.iluwatar.builder.Hero.Builder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
@ -50,6 +52,8 @@ import com.iluwatar.builder.Hero.Builder;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -60,18 +64,18 @@ public class App {
Hero mage =
new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK)
.withWeapon(Weapon.DAGGER).build();
System.out.println(mage);
LOGGER.info(mage.toString());
Hero warrior =
new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
.withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
.build();
System.out.println(warrior);
LOGGER.info(warrior.toString());
Hero thief =
new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD)
.withWeapon(Weapon.BOW).build();
System.out.println(thief);
LOGGER.info(thief.toString());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.business.delegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Service EJB implementation
@ -29,8 +32,10 @@ package com.iluwatar.business.delegate;
*/
public class EjbService implements BusinessService {
private static final Logger LOGGER = LoggerFactory.getLogger(EjbService.class);
@Override
public void doProcessing() {
System.out.println("EjbService is now processing");
LOGGER.info("EjbService is now processing");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.business.delegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Service JMS implementation
@ -29,8 +32,10 @@ package com.iluwatar.business.delegate;
*/
public class JmsService implements BusinessService {
private static final Logger LOGGER = LoggerFactory.getLogger(JmsService.class);
@Override
public void doProcessing() {
System.out.println("JmsService is now processing");
LOGGER.info("JmsService is now processing");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
@ -60,6 +63,9 @@ package com.iluwatar.caching;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -82,13 +88,13 @@ public class App {
* Read-through and write-through
*/
public void useReadAndWriteThroughStrategy() {
System.out.println("# CachingPolicy.THROUGH");
LOGGER.info("# CachingPolicy.THROUGH");
AppManager.initCachingPolicy(CachingPolicy.THROUGH);
UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy.");
AppManager.save(userAccount1);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("001");
AppManager.find("001");
}
@ -97,21 +103,21 @@ public class App {
* Read-through and write-around
*/
public void useReadThroughAndWriteAroundStrategy() {
System.out.println("# CachingPolicy.AROUND");
LOGGER.info("# CachingPolicy.AROUND");
AppManager.initCachingPolicy(CachingPolicy.AROUND);
UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl.");
AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("002");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
userAccount2 = AppManager.find("002");
userAccount2.setUserName("Jane G.");
AppManager.save(userAccount2);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("002");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("002");
}
@ -119,7 +125,7 @@ public class App {
* Read-through and write-behind
*/
public void useReadThroughAndWriteBehindStrategy() {
System.out.println("# CachingPolicy.BEHIND");
LOGGER.info("# CachingPolicy.BEHIND");
AppManager.initCachingPolicy(CachingPolicy.BEHIND);
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
@ -129,23 +135,23 @@ public class App {
AppManager.save(userAccount3);
AppManager.save(userAccount4);
AppManager.save(userAccount5);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("003");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child.");
AppManager.save(userAccount6);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("004");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
}
/**
* Cache-Aside
*/
public void useCacheAsideStategy() {
System.out.println("# CachingPolicy.ASIDE");
LOGGER.info("# CachingPolicy.ASIDE");
AppManager.initCachingPolicy(CachingPolicy.ASIDE);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food.");
UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
@ -154,10 +160,10 @@ public class App {
AppManager.save(userAccount4);
AppManager.save(userAccount5);
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("003");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
AppManager.find("004");
System.out.println(AppManager.printCacheContent());
LOGGER.info(AppManager.printCacheContent());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
@ -31,6 +34,8 @@ import java.util.List;
*/
public class CacheStore {
private static final Logger LOGGER = LoggerFactory.getLogger(CacheStore.class);
static LruCache cache;
private CacheStore() {
@ -52,10 +57,10 @@ public class CacheStore {
*/
public static UserAccount readThrough(String userId) {
if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
LOGGER.info("# Cache Hit!");
return cache.get(userId);
}
System.out.println("# Cache Miss!");
LOGGER.info("# Cache Miss!");
UserAccount userAccount = DbManager.readFromDb(userId);
cache.set(userId, userAccount);
return userAccount;
@ -91,13 +96,13 @@ public class CacheStore {
*/
public static UserAccount readThroughWithWriteBackPolicy(String userId) {
if (cache.contains(userId)) {
System.out.println("# Cache Hit!");
LOGGER.info("# Cache Hit!");
return cache.get(userId);
}
System.out.println("# Cache Miss!");
LOGGER.info("# Cache Miss!");
UserAccount userAccount = DbManager.readFromDb(userId);
if (cache.isFull()) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
LOGGER.info("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb);
}
@ -110,7 +115,7 @@ public class CacheStore {
*/
public static void writeBehind(UserAccount userAccount) {
if (cache.isFull() && !cache.contains(userAccount.getUserId())) {
System.out.println("# Cache is FULL! Writing LRU data to DB...");
LOGGER.info("# Cache is FULL! Writing LRU data to DB...");
UserAccount toBeWrittenToDb = cache.getLruData();
DbManager.upsertDb(toBeWrittenToDb);
}
@ -130,7 +135,7 @@ public class CacheStore {
* Writes remaining content in the cache into the DB.
*/
public static void flushCache() {
System.out.println("# flushCache...");
LOGGER.info("# flushCache...");
if (null == cache) {
return;
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.caching;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -38,6 +41,8 @@ import java.util.Map;
*/
public class LruCache {
private static final Logger LOGGER = LoggerFactory.getLogger(LruCache.class);
class Node {
String userId;
UserAccount userAccount;
@ -115,7 +120,7 @@ public class LruCache {
} else {
Node newNode = new Node(userId, userAccount);
if (cache.size() >= capacity) {
System.out.println("# Cache is FULL! Removing " + end.userId + " from cache...");
LOGGER.info("# Cache is FULL! Removing {} from cache...", end.userId);
cache.remove(end.userId); // remove LRU data from cache.
remove(end);
setHead(newNode);
@ -136,7 +141,7 @@ public class LruCache {
public void invalidate(String userId) {
Node toBeRemoved = cache.remove(userId);
if (toBeRemoved != null) {
System.out.println("# " + userId + " has been updated! Removing older version from cache...");
LOGGER.info("# {} has been updated! Removing older version from cache...", userId);
remove(toBeRemoved);
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Callback pattern is more native for functional languages where functions are treated as
@ -31,6 +34,8 @@ package com.iluwatar.callback;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*/
@ -39,7 +44,7 @@ public class App {
Callback callback = new Callback() {
@Override
public void call() {
System.out.println("I'm done now.");
LOGGER.info("I'm done now.");
}
};
task.executeWith(callback);

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* This example generates the exact same output as {@link App} however the callback has been
@ -30,12 +33,14 @@ package com.iluwatar.callback;
*/
public class LambdasApp {
private static final Logger LOGGER = LoggerFactory.getLogger(LambdasApp.class);
/**
* Program entry point
*/
public static void main(String[] args) {
Task task = new SimpleTask();
Callback c = () -> System.out.println("I'm done now.");
Callback c = () -> LOGGER.info("I'm done now.");
task.executeWith(c);
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Implementation of task that need to be executed
@ -29,8 +32,10 @@ package com.iluwatar.callback;
*/
public class SimpleTask extends Task {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTask.class);
@Override
public void execute() {
System.out.println("Perform some important activity and after call the callback method.");
LOGGER.info("Perform some important activity and after call the callback method.");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.chain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* RequestHandler
@ -29,6 +32,8 @@ package com.iluwatar.chain;
*/
public abstract class RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
private RequestHandler next;
public RequestHandler(RequestHandler next) {
@ -45,7 +50,7 @@ public abstract class RequestHandler {
}
protected void printHandling(Request req) {
System.out.println(this + " handling request \"" + req + "\"");
LOGGER.info("{} handling request \"{}\"", this, req);
}
@Override

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Base class for spell targets.
@ -29,6 +32,8 @@ package com.iluwatar.command;
*/
public abstract class Target {
private static final Logger LOGGER = LoggerFactory.getLogger(Target.class);
private Size size;
private Visibility visibility;
@ -56,8 +61,6 @@ public abstract class Target {
* Print status
*/
public void printStatus() {
System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(),
getVisibility()));
System.out.println();
LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Deque;
import java.util.LinkedList;
@ -32,6 +35,8 @@ import java.util.LinkedList;
*/
public class Wizard {
private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class);
private Deque<Command> undoStack = new LinkedList<>();
private Deque<Command> redoStack = new LinkedList<>();
@ -41,7 +46,7 @@ public class Wizard {
* Cast spell
*/
public void castSpell(Command command, Target target) {
System.out.println(this + " casts " + command + " at " + target);
LOGGER.info("{} casts {} at {}", this, command, target);
command.execute(target);
undoStack.offerLast(command);
}
@ -53,7 +58,7 @@ public class Wizard {
if (!undoStack.isEmpty()) {
Command previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell);
System.out.println(this + " undoes " + previousSpell);
LOGGER.info("{} undoes {}", this, previousSpell);
previousSpell.undo();
}
}
@ -65,7 +70,7 @@ public class Wizard {
if (!redoStack.isEmpty()) {
Command previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell);
System.out.println(this + " redoes " + previousSpell);
LOGGER.info("{} redoes {}", this, previousSpell);
previousSpell.redo();
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.composite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Composite pattern is a partitioning design pattern. The Composite pattern describes that a
* group of objects is to be treated in the same way as a single instance of an object. The intent
@ -35,20 +38,22 @@ package com.iluwatar.composite;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
* @param args command line args
*/
public static void main(String[] args) {
System.out.println("Message from the orcs: ");
LOGGER.info("Message from the orcs: ");
LetterComposite orcMessage = new Messenger().messageFromOrcs();
orcMessage.print();
System.out.println("\n");
LOGGER.info("\n");
System.out.println("Message from the elves: ");
LOGGER.info("Message from the elves: ");
LetterComposite elfMessage = new Messenger().messageFromElves();
elfMessage.print();

View File

@ -23,7 +23,7 @@
package com.iluwatar.composite;
/**
*
*
* Letter
*
*/

View File

@ -25,7 +25,7 @@ package com.iluwatar.composite;
import java.util.List;
/**
*
*
* Sentence
*
*/

View File

@ -25,7 +25,7 @@ package com.iluwatar.composite;
import java.util.List;
/**
*
*
* Word
*
*/

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The Decorator pattern is a more flexible alternative to subclassing. The Decorator class
@ -36,6 +39,8 @@ package com.iluwatar.decorator;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -44,17 +49,17 @@ public class App {
public static void main(String[] args) {
// simple troll
System.out.println("A simple looking troll approaches.");
LOGGER.info("A simple looking troll approaches.");
Hostile troll = new Troll();
troll.attack();
troll.fleeBattle();
System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
LOGGER.info("Simple troll power {}.\n", troll.getAttackPower());
// change the behavior of the simple troll by adding a decorator
System.out.println("\nA smart looking troll surprises you.");
LOGGER.info("A smart looking troll surprises you.");
Hostile smart = new SmartHostile(troll);
smart.attack();
smart.fleeBattle();
System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
LOGGER.info("Smart troll power {}.\n", smart.getAttackPower());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface
* are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile}
@ -30,6 +33,8 @@ package com.iluwatar.decorator;
*/
public class SmartHostile implements Hostile {
private static final Logger LOGGER = LoggerFactory.getLogger(SmartHostile.class);
private Hostile decorated;
public SmartHostile(Hostile decorated) {
@ -38,7 +43,7 @@ public class SmartHostile implements Hostile {
@Override
public void attack() {
System.out.println("It throws a rock at you!");
LOGGER.info("It throws a rock at you!");
decorated.attack();
}
@ -50,7 +55,7 @@ public class SmartHostile implements Hostile {
@Override
public void fleeBattle() {
System.out.println("It calls for help!");
LOGGER.info("It calls for help!");
decorated.fleeBattle();
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.decorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Troll implements {@link Hostile} interface directly.
@ -29,9 +32,11 @@ package com.iluwatar.decorator;
*/
public class Troll implements Hostile {
private static final Logger LOGGER = LoggerFactory.getLogger(Troll.class);
@Override
public void attack() {
System.out.println("The troll swings at you with a club!");
LOGGER.info("The troll swings at you with a club!");
}
@Override
@ -41,6 +46,6 @@ public class Troll implements Hostile {
@Override
public void fleeBattle() {
System.out.println("The troll shrieks in horror and runs away!");
LOGGER.info("The troll shrieks in horror and runs away!");
}
}

View File

@ -22,16 +22,18 @@
*/
package com.iluwatar.decorator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
import static org.mockito.internal.verification.VerificationModeFactory.times;
/**
* Date: 12/7/15 - 7:26 PM
@ -40,31 +42,16 @@ import static org.mockito.internal.verification.VerificationModeFactory.times;
*/
public class TrollTest {
/**
* The mocked standard out stream, required since the actions don't have any influence on other
* objects, except for writing to the std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
private InMemoryAppender appender;
/**
* 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);
appender = new InMemoryAppender(Troll.class);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
appender.stop();
}
@Test
@ -73,12 +60,34 @@ public class TrollTest {
assertEquals(10, troll.getAttackPower());
troll.attack();
verify(this.stdOutMock, times(1)).println(eq("The troll swings at you with a club!"));
assertEquals("The troll swings at you with a club!", appender.getLastMessage());
troll.fleeBattle();
verify(this.stdOutMock, times(1)).println(eq("The troll shrieks in horror and runs away!"));
assertEquals("The troll shrieks in horror and runs away!", appender.getLastMessage());
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(2, appender.getLogSize());
}
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getMessage();
}
public int getLogSize() {
return log.size();
}
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Specialised Implementation of {@link Printer} for a Canon Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/
public class CanonPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(CanonPrinter.class);
/**
* {@inheritDoc}
*/
@Override
public void print(String message) {
System.out.print("Canon Printer : " + message);
LOGGER.info("Canon Printer : {}", message);
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Specialised Implementation of {@link Printer} for a Epson Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/
public class EpsonPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(EpsonPrinter.class);
/**
* {@inheritDoc}
*/
@Override
public void print(String message) {
System.out.print("Epson Printer : " + message);
LOGGER.info("Epson Printer : {}", message);
}
}

View File

@ -23,6 +23,8 @@
package com.iluwatar.delegation.simple.printers;
import com.iluwatar.delegation.simple.Printer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Specialised Implementation of {@link Printer} for a HP Printer, in
@ -32,12 +34,14 @@ import com.iluwatar.delegation.simple.Printer;
*/
public class HpPrinter implements Printer {
private static final Logger LOGGER = LoggerFactory.getLogger(HpPrinter.class);
/**
* {@inheritDoc}
*/
@Override
public void print(String message) {
System.out.print("HP Printer : " + message);
LOGGER.info("HP Printer : {}", message);
}
}

View File

@ -22,28 +22,44 @@
*/
package com.iluwatar.delegation.simple;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import com.iluwatar.delegation.simple.printers.CanonPrinter;
import com.iluwatar.delegation.simple.printers.EpsonPrinter;
import com.iluwatar.delegation.simple.printers.HpPrinter;
import org.junit.Rule;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class DelegateTest {
private static final String MESSAGE = "Test Message Printed";
private InMemoryAppender appender;
@Rule
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
private static final String MESSAGE = "Test Message Printed";
@Test
public void testCanonPrinter() throws Exception {
PrinterController printerController = new PrinterController(new CanonPrinter());
printerController.print(MESSAGE);
assertEquals("Canon Printer : Test Message Printed", systemOutRule.getLog());
assertEquals("Canon Printer : Test Message Printed", appender.getLastMessage());
}
@Test
@ -51,7 +67,7 @@ public class DelegateTest {
PrinterController printerController = new PrinterController(new HpPrinter());
printerController.print(MESSAGE);
assertEquals("HP Printer : Test Message Printed", systemOutRule.getLog());
assertEquals("HP Printer : Test Message Printed", appender.getLastMessage());
}
@Test
@ -59,7 +75,30 @@ public class DelegateTest {
PrinterController printerController = new PrinterController(new EpsonPrinter());
printerController.print(MESSAGE);
assertEquals("Epson Printer : Test Message Printed", systemOutRule.getLog());
assertEquals("Epson Printer : Test Message Printed", appender.getLastMessage());
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.dependency.injection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Tobacco abstraction
@ -29,8 +32,10 @@ package com.iluwatar.dependency.injection;
*/
public abstract class Tobacco {
private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class);
public void smoke(Wizard wizard) {
System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this
.getClass().getSimpleName()));
LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(),
this.getClass().getSimpleName());
}
}

View File

@ -22,18 +22,31 @@
*/
package com.iluwatar.dependency.injection;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/10/15 - 8:40 PM
*
* @author Jeroen Meulemeester
*/
public class AdvancedWizardTest extends StdOutTest {
public class AdvancedWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/**
* Test if the {@link AdvancedWizard} smokes whatever instance of {@link Tobacco} is passed to him
@ -51,12 +64,13 @@ public class AdvancedWizardTest extends StdOutTest {
advancedWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("AdvancedWizard smoking " + tobacco.getClass().getSimpleName());
assertEquals("AdvancedWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage());
// ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock());
}
// ... and nothing else is happening.
assertEquals(tobaccos.length, appender.getLogSize());
}
}
}

View File

@ -25,19 +25,31 @@ package com.iluwatar.dependency.injection;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/10/15 - 8:57 PM
*
* @author Jeroen Meulemeester
*/
public class GuiceWizardTest extends StdOutTest {
public class GuiceWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/**
* Test if the {@link GuiceWizard} smokes whatever instance of {@link Tobacco} is passed to him
@ -55,12 +67,11 @@ public class GuiceWizardTest extends StdOutTest {
guiceWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobacco.getClass().getSimpleName());
// ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock());
assertEquals("GuiceWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage());
}
// ... and nothing else is happening.
assertEquals(tobaccos.length, appender.getLogSize());
}
/**
@ -89,12 +100,11 @@ public class GuiceWizardTest extends StdOutTest {
guiceWizard.smoke();
// Verify if the wizard is smoking the correct tobacco ...
verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobaccoClass.getSimpleName());
// ... and nothing else is happening.
verifyNoMoreInteractions(getStdOutMock());
assertEquals("GuiceWizard smoking " + tobaccoClass.getSimpleName(), appender.getLastMessage());
}
// ... and nothing else is happening.
assertEquals(tobaccos.length, appender.getLogSize());
}
}
}

View File

@ -22,16 +22,31 @@
*/
package com.iluwatar.dependency.injection;
import com.iluwatar.dependency.injection.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.*;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/10/15 - 8:26 PM
*
* @author Jeroen Meulemeester
*/
public class SimpleWizardTest extends StdOutTest {
public class SimpleWizardTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(Tobacco.class);
}
@After
public void tearDown() {
appender.stop();
}
/**
* Test if the {@link SimpleWizard} does the only thing it can do: Smoke it's {@link
@ -41,8 +56,8 @@ public class SimpleWizardTest extends StdOutTest {
public void testSmoke() {
final SimpleWizard simpleWizard = new SimpleWizard();
simpleWizard.smoke();
verify(getStdOutMock(), times(1)).println("SimpleWizard smoking OldTobyTobacco");
verifyNoMoreInteractions(getStdOutMock());
assertEquals("SimpleWizard smoking OldTobyTobacco", appender.getLastMessage());
assertEquals(1, appender.getLogSize());
}
}
}

View File

@ -1,75 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.dependency.injection;
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 wizard 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;
}
}

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.dependency.injection.utils;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.doublechecked.locking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -40,6 +43,8 @@ import java.util.concurrent.TimeUnit;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -58,7 +63,7 @@ public class App {
try {
executorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Error waiting for ExecutorService shutdown");
LOGGER.error("Error waiting for ExecutorService shutdown");
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.doublechecked.locking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -35,6 +38,8 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class Inventory {
private static final Logger LOGGER = LoggerFactory.getLogger(Inventory.class);
private final int inventorySize;
private final List<Item> items;
private final Lock lock;
@ -57,8 +62,7 @@ public class Inventory {
try {
if (items.size() < inventorySize) {
items.add(item);
System.out.println(Thread.currentThread() + ": items.size()=" + items.size()
+ ", inventorySize=" + inventorySize);
LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items.size(), inventorySize);
return true;
}
} finally {

View File

@ -0,0 +1,52 @@
<!--
The MIT License
Copyright (c) 2014 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>double-checked-locking.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>double-checked-locking-%d.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<logger name="com.iluwatar" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="FILE"/>
</logger>
<root level="WARN">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

View File

@ -22,24 +22,23 @@
*/
package com.iluwatar.doublechecked.locking;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertNotNull;
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.junit.Assert.assertTrue;
/**
* Date: 12/10/15 - 9:34 PM
@ -48,31 +47,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/
public class InventoryTest {
/**
* The mocked standard out {@link PrintStream}, used to verify a steady increasing size of the
* {@link Inventory} while adding items from multiple threads concurrently
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
private InMemoryAppender appender;
/**
* 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);
appender = new InMemoryAppender(Inventory.class);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
appender.stop();
}
/**
@ -112,21 +96,32 @@ public class InventoryTest {
assertNotNull(items);
assertEquals(INVENTORY_SIZE, items.size());
// Capture all stdOut messages ...
final ArgumentCaptor<String> stdOutCaptor = ArgumentCaptor.forClass(String.class);
verify(this.stdOutMock, times(INVENTORY_SIZE)).println(stdOutCaptor.capture());
// ... verify if we got all 1000
final List<String> values = stdOutCaptor.getAllValues();
assertEquals(INVENTORY_SIZE, values.size());
assertEquals(INVENTORY_SIZE, appender.getLogSize());
// ... and check if the inventory size is increasing continuously
for (int i = 0; i < values.size(); i++) {
assertNotNull(values.get(i));
assertTrue(values.get(i).contains("items.size()=" + (i + 1)));
for (int i = 0; i < items.size(); i++) {
assertTrue(appender.log.get(i).getFormattedMessage().contains("items.size()=" + (i + 1)));
}
verifyNoMoreInteractions(this.stdOutMock);
}
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
@ -45,6 +48,8 @@ import java.util.List;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -58,8 +63,8 @@ public class App {
objects.add(new SpaceStationMir(1, 1, 2, 2));
objects.add(new Meteoroid(10, 10, 15, 15));
objects.add(new SpaceStationIss(12, 12, 14, 14));
objects.stream().forEach(o -> System.out.println(o));
System.out.println("");
objects.stream().forEach(o -> LOGGER.info(o.toString()));
LOGGER.info("");
// collision check
objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> {
@ -67,10 +72,10 @@ public class App {
o1.collision(o2);
}
}));
System.out.println("");
LOGGER.info("");
// output eventual object statuses
objects.stream().forEach(o -> System.out.println(o));
System.out.println("");
objects.stream().forEach(o -> LOGGER.info(o.toString()));
LOGGER.info("");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Meteoroid game object
@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch;
*/
public class Meteoroid extends GameObject {
private static final Logger LOGGER = LoggerFactory.getLogger(Meteoroid.class);
public Meteoroid(int left, int top, int right, int bottom) {
super(left, top, right, bottom);
}
@ -40,25 +45,21 @@ public class Meteoroid extends GameObject {
@Override
public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this
.getClass().getSimpleName()));
LOGGER.info("{} hits {}.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName());
}
@Override
public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this
.getClass().getSimpleName()));
LOGGER.info("{} hits {}.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName());
}
@Override
public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass()
.getSimpleName()));
LOGGER.info("{} hits {}.", mir.getClass().getSimpleName(), this.getClass().getSimpleName());
}
@Override
public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass()
.getSimpleName()));
LOGGER.info("{} hits {}.", iss.getClass().getSimpleName(), this.getClass().getSimpleName());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.doubledispatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Space station Mir game object
@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch;
*/
public class SpaceStationMir extends GameObject {
private static final Logger LOGGER = LoggerFactory.getLogger(SpaceStationMir.class);
public SpaceStationMir(int left, int top, int right, int bottom) {
super(left, top, right, bottom);
}
@ -40,31 +45,30 @@ public class SpaceStationMir extends GameObject {
@Override
public void collisionResolve(FlamingAsteroid asteroid) {
System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid
.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass()
.getSimpleName(), this.getClass().getSimpleName()));
LOGGER.info("{} hits {}. {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true);
setOnFire(true);
}
@Override
public void collisionResolve(Meteoroid meteoroid) {
System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass()
.getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()));
LOGGER.info("{} hits {}. {} is damaged!", meteoroid.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true);
}
@Override
public void collisionResolve(SpaceStationMir mir) {
System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName()));
LOGGER.info("{} hits {}. {} is damaged!", mir.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true);
}
@Override
public void collisionResolve(SpaceStationIss iss) {
System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName()));
LOGGER.info("{} hits {}. {} is damaged!", iss.getClass().getSimpleName(),
this.getClass().getSimpleName(), this.getClass().getSimpleName());
setDamaged(true);
}
}

View File

@ -22,17 +22,9 @@
*/
package com.iluwatar.doubledispatch;
import org.junit.After;
import org.junit.Before;
import java.io.PrintStream;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Date: 12/10/15 - 8:37 PM
@ -41,43 +33,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/
public abstract class CollisionTest<O extends GameObject> {
/**
* The mocked standard out {@link PrintStream}, required if some of the actions on the tested
* object don't have a direct 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;
}
/**
* Get the tested object
*
@ -106,9 +61,6 @@ public abstract class CollisionTest<O extends GameObject> {
tested.collision(other);
verify(getStdOutMock(), times(1)).println(description);
verifyNoMoreInteractions(getStdOutMock());
testOnFire(other, tested, otherOnFire);
testDamaged(other, tested, otherDamaged);
@ -129,8 +81,8 @@ public abstract class CollisionTest<O extends GameObject> {
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!"
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());
@ -149,7 +101,7 @@ public abstract class CollisionTest<O extends GameObject> {
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 + "] 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());

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.event.aggregator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* KingJoffrey observes events from {@link KingsHand}.
@ -29,8 +32,10 @@ package com.iluwatar.event.aggregator;
*/
public class KingJoffrey implements EventObserver {
private static final Logger LOGGER = LoggerFactory.getLogger(KingJoffrey.class);
@Override
public void onEvent(Event e) {
System.out.println("Received event from the King's Hand: " + e.toString());
LOGGER.info("Received event from the King's Hand: {}", e.toString());
}
}

View File

@ -22,17 +22,18 @@
*/
package com.iluwatar.event.aggregator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.LinkedList;
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.verifyNoMoreInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/12/15 - 3:04 PM
@ -41,31 +42,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
*/
public class KingJoffreyTest {
/**
* The mocked standard out {@link PrintStream}, required since {@link KingJoffrey} does nothing
* except for writing to std-out using {@link System#out}
*/
private final PrintStream stdOutMock = mock(PrintStream.class);
private InMemoryAppender appender;
/**
* 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);
appender = new InMemoryAppender(KingJoffrey.class);
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
appender.stop();
}
/**
@ -75,15 +61,38 @@ public class KingJoffreyTest {
public void testOnEvent() {
final KingJoffrey kingJoffrey = new KingJoffrey();
for (final Event event : Event.values()) {
verifyZeroInteractions(this.stdOutMock);
for (int i = 0; i < Event.values().length; ++i) {
assertEquals(i, appender.getLogSize());
Event event = Event.values()[i];
kingJoffrey.onEvent(event);
final String expectedMessage = "Received event from the King's Hand: " + event.toString();
verify(this.stdOutMock, times(1)).println(expectedMessage);
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(expectedMessage, appender.getLastMessage());
assertEquals(i + 1, appender.getLogSize());
}
}
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}
}

View File

@ -16,38 +16,43 @@
*/
package com.iluwatar.event.asynchronous;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Scanner;
/**
*
*
* This application demonstrates the <b>Event-based Asynchronous</b> pattern. Essentially, users (of the pattern) may
* choose to run events in an Asynchronous or Synchronous mode. There can be multiple Asynchronous events running at
* once but only one Synchronous event can run at a time. Asynchronous events are synonymous to multi-threads. The key
* point here is that the threads run in the background and the user is free to carry on with other processes. Once an
* event is complete, the appropriate listener/callback method will be called. The listener then proceeds to carry out
* further processing depending on the needs of the user.
*
*
* The {@link EventManager} manages the events/threads that the user creates. Currently, the supported event operations
* are: <code>start</code>, <code>stop</code>, <code>getStatus</code>. For Synchronous events, the user is unable to
* start another (Synchronous) event if one is already running at the time. The running event would have to either be
* stopped or completed before a new event can be started.
*
*
* The Event-based Asynchronous Pattern makes available the advantages of multithreaded applications while hiding many
* of the complex issues inherent in multithreaded design. Using a class that supports this pattern can allow you to:-
* (1) Perform time-consuming tasks, such as downloads and database operations, "in the background," without
* interrupting your application. (2) Execute multiple operations simultaneously, receiving notifications when each
* completes. (3) Wait for resources to become available without stopping ("hanging") your application. (4) Communicate
* with pending asynchronous operations using the familiar events-and-delegates model.
*
*
* @see EventManager
* @see Event
*
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static final String PROP_FILE_NAME = "config.properties";
boolean interactiveMode = false;
@ -77,7 +82,7 @@ public class App {
try {
prop.load(inputStream);
} catch (IOException e) {
System.out.println(PROP_FILE_NAME + " was not found. Defaulting to non-interactive mode.");
LOGGER.error("{} was not found. Defaulting to non-interactive mode.", PROP_FILE_NAME, e);
}
String property = prop.getProperty("INTERACTIVE_MODE");
if (property.equalsIgnoreCase("YES")) {
@ -106,27 +111,27 @@ public class App {
try {
// Create an Asynchronous event.
int aEventId = eventManager.createAsync(60);
System.out.println("Async Event [" + aEventId + "] has been created.");
LOGGER.info("Async Event [{}] has been created.", aEventId);
eventManager.start(aEventId);
System.out.println("Async Event [" + aEventId + "] has been started.");
LOGGER.info("Async Event [{}] has been started.", aEventId);
// Create a Synchronous event.
int sEventId = eventManager.create(60);
System.out.println("Sync Event [" + sEventId + "] has been created.");
LOGGER.info("Sync Event [{}] has been created.", sEventId);
eventManager.start(sEventId);
System.out.println("Sync Event [" + sEventId + "] has been started.");
LOGGER.info("Sync Event [{}] has been started.", sEventId);
eventManager.status(aEventId);
eventManager.status(sEventId);
eventManager.cancel(aEventId);
System.out.println("Async Event [" + aEventId + "] has been stopped.");
LOGGER.info("Async Event [{}] has been stopped.", aEventId);
eventManager.cancel(sEventId);
System.out.println("Sync Event [" + sEventId + "] has been stopped.");
LOGGER.info("Sync Event [{}] has been stopped.", sEventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
@ -139,58 +144,58 @@ public class App {
Scanner s = new Scanner(System.in);
int option = -1;
while (option != 4) {
System.out.println("Hello. Would you like to boil some eggs?");
System.out.println("(1) BOIL AN EGG \n(2) STOP BOILING THIS EGG \n(3) HOW ARE MY EGGS? \n(4) EXIT");
System.out.print("Choose [1,2,3,4]: ");
LOGGER.info("Hello. Would you like to boil some eggs?");
LOGGER.info("(1) BOIL AN EGG \n(2) STOP BOILING THIS EGG \n(3) HOW ARE MY EGGS? \n(4) EXIT");
LOGGER.info("Choose [1,2,3,4]: ");
option = s.nextInt();
if (option == 1) {
s.nextLine();
System.out.print("Boil multiple eggs at once (A) or boil them one-by-one (S)?: ");
LOGGER.info("Boil multiple eggs at once (A) or boil them one-by-one (S)?: ");
String eventType = s.nextLine();
System.out.print("How long should this egg be boiled for (in seconds)?: ");
LOGGER.info("How long should this egg be boiled for (in seconds)?: ");
int eventTime = s.nextInt();
if (eventType.equalsIgnoreCase("A")) {
try {
int eventId = eventManager.createAsync(eventTime);
eventManager.start(eventId);
System.out.println("Egg [" + eventId + "] is being boiled.");
LOGGER.info("Egg [{}] is being boiled.", eventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
} else if (eventType.equalsIgnoreCase("S")) {
try {
int eventId = eventManager.create(eventTime);
eventManager.start(eventId);
System.out.println("Egg [" + eventId + "] is being boiled.");
LOGGER.info("Egg [{}] is being boiled.", eventId);
} catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException
| EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
} else {
System.out.println("Unknown event type.");
LOGGER.info("Unknown event type.");
}
} else if (option == 2) {
System.out.print("Which egg?: ");
LOGGER.info("Which egg?: ");
int eventId = s.nextInt();
try {
eventManager.cancel(eventId);
System.out.println("Egg [" + eventId + "] is removed from boiler.");
LOGGER.info("Egg [{}] is removed from boiler.", eventId);
} catch (EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
} else if (option == 3) {
s.nextLine();
System.out.print("Just one egg (O) OR all of them (A) ?: ");
LOGGER.info("Just one egg (O) OR all of them (A) ?: ");
String eggChoice = s.nextLine();
if (eggChoice.equalsIgnoreCase("O")) {
System.out.print("Which egg?: ");
LOGGER.info("Which egg?: ");
int eventId = s.nextInt();
try {
eventManager.status(eventId);
} catch (EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
} else if (eggChoice.equalsIgnoreCase("A")) {
eventManager.statusOfAllEvents();

View File

@ -16,13 +16,18 @@
*/
package com.iluwatar.event.asynchronous;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*
* Each Event runs as a separate/individual thread.
*
*/
public class Event implements IEvent, Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(Event.class);
private int eventId;
private int eventTime;
private boolean isSynchronous;
@ -31,7 +36,7 @@ public class Event implements IEvent, Runnable {
private ThreadCompleteListener eventListener;
/**
*
*
* @param eventId event ID
* @param eventTime event time
* @param isSynchronous is of synchronous type
@ -63,9 +68,9 @@ public class Event implements IEvent, Runnable {
@Override
public void status() {
if (!isComplete) {
System.out.println("[" + eventId + "] is not done.");
LOGGER.info("[{}] is not done.", eventId);
} else {
System.out.println("[" + eventId + "] is done.");
LOGGER.info("[{}] is done.", eventId);
}
}

View File

@ -22,7 +22,7 @@ import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*
* EventManager handles and maintains a pool of event threads. {@link Event} threads are created upon user request. Thre
* are two types of events; Asynchronous and Synchronous. There can be multiple Asynchronous events running at once but
* only one Synchronous event running at a time. Currently supported event operations are: start, stop, and getStatus.
@ -52,7 +52,7 @@ public class EventManager implements ThreadCompleteListener {
/**
* Create a Synchronous event.
*
*
* @param eventTime Time an event should run for.
* @return eventId
* @throws MaxNumOfEventsAllowedException When too many events are running at a time.
@ -74,7 +74,7 @@ public class EventManager implements ThreadCompleteListener {
/**
* Create an Asynchronous event.
*
*
* @param eventTime Time an event should run for.
* @return eventId
* @throws MaxNumOfEventsAllowedException When too many events are running at a time.
@ -106,7 +106,7 @@ public class EventManager implements ThreadCompleteListener {
/**
* Starts event.
*
*
* @param eventId The event that needs to be started.
* @throws EventDoesNotExistException If event does not exist in our eventPool.
*/
@ -120,7 +120,7 @@ public class EventManager implements ThreadCompleteListener {
/**
* Stops event.
*
*
* @param eventId The event that needs to be stopped.
* @throws EventDoesNotExistException If event does not exist in our eventPool.
*/
@ -139,7 +139,7 @@ public class EventManager implements ThreadCompleteListener {
/**
* Get status of a running event.
*
*
* @param eventId The event to inquire status of.
* @throws EventDoesNotExistException If event does not exist in our eventPool.
*/

View File

@ -16,10 +16,12 @@
*/
package com.iluwatar.event.asynchronous;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertTrue;
/**
*
@ -29,6 +31,8 @@ import org.junit.Test;
public class EventAsynchronousTest {
App app;
private static final Logger LOGGER = LoggerFactory.getLogger(EventAsynchronousTest.class);
@Before
public void setUp() {
app = new App();
@ -46,7 +50,7 @@ public class EventAsynchronousTest {
eventManager.cancel(aEventId);
assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
@ -63,7 +67,7 @@ public class EventAsynchronousTest {
assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
@ -76,7 +80,7 @@ public class EventAsynchronousTest {
sEventId = eventManager.create(60);
eventManager.start(sEventId);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
@ -101,7 +105,7 @@ public class EventAsynchronousTest {
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException
| InvalidOperationException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
@ -129,7 +133,7 @@ public class EventAsynchronousTest {
assertTrue(eventManager.getEventPool().size() == 0);
} catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) {
System.out.println(e.getMessage());
LOGGER.error(e.getMessage());
}
}
}

View File

@ -24,17 +24,19 @@ package com.iluwatar.eda.handler;
import com.iluwatar.eda.event.UserCreatedEvent;
import com.iluwatar.eda.framework.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Handles the {@link UserCreatedEvent} message.
*/
public class UserCreatedEventHandler implements Handler<UserCreatedEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserCreatedEventHandler.class);
@Override
public void onEvent(UserCreatedEvent event) {
System.out.println(String.format(
"User '%s' has been Created!", event.getUser().getUsername()));
LOGGER.info("User '{}' has been Created!", event.getUser().getUsername());
}
}

View File

@ -24,16 +24,18 @@ package com.iluwatar.eda.handler;
import com.iluwatar.eda.event.UserUpdatedEvent;
import com.iluwatar.eda.framework.Handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Handles the {@link UserUpdatedEvent} message.
*/
public class UserUpdatedEventHandler implements Handler<UserUpdatedEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(UserUpdatedEventHandler.class);
@Override
public void onEvent(UserUpdatedEvent event) {
System.out.println(String.format(
"User '%s' has been Updated!", event.getUser().getUsername()));
LOGGER.info("User '{}' has been Updated!", event.getUser().getUsername());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* DwarvenCartOperator is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/
public class DwarvenCartOperator extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenCartOperator.class);
@Override
public void work() {
System.out.println(name() + " moves gold chunks out of the mine.");
LOGGER.info("{} moves gold chunks out of the mine.", name());
}
@Override

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* DwarvenGoldDigger is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/
public class DwarvenGoldDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenGoldDigger.class);
@Override
public void work() {
System.out.println(name() + " digs for gold.");
LOGGER.info("{} digs for gold.", name());
}
@Override

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* DwarvenMineWorker is one of the goldmine subsystems.
@ -29,20 +32,22 @@ package com.iluwatar.facade;
*/
public abstract class DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenMineWorker.class);
public void goToSleep() {
System.out.println(name() + " goes to sleep.");
LOGGER.info("{} goes to sleep.", name());
}
public void wakeUp() {
System.out.println(name() + " wakes up.");
LOGGER.info("{} wakes up.", name());
}
public void goHome() {
System.out.println(name() + " goes home.");
LOGGER.info("{} goes home.", name());
}
public void goToMine() {
System.out.println(name() + " goes to the mine.");
LOGGER.info("{} goes to the mine.", name());
}
private void action(Action action) {
@ -63,7 +68,7 @@ public abstract class DwarvenMineWorker {
work();
break;
default:
System.out.println("Undefined action");
LOGGER.info("Undefined action");
break;
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* DwarvenTunnelDigger is one of the goldmine subsystems.
@ -29,9 +32,11 @@ package com.iluwatar.facade;
*/
public class DwarvenTunnelDigger extends DwarvenMineWorker {
private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenTunnelDigger.class);
@Override
public void work() {
System.out.println(name() + " creates another promising tunnel.");
LOGGER.info("{} creates another promising tunnel.", name());
}
@Override

View File

@ -22,17 +22,19 @@
*/
package com.iluwatar.facade;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Date: 12/9/15 - 9:40 PM
@ -41,35 +43,19 @@ import static org.mockito.internal.verification.VerificationModeFactory.times;
*/
public class DwarvenGoldmineFacadeTest {
/**
* The mocked standard out {@link PrintStream}, required since the actions on the gold mine facade
* 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);
private InMemoryAppender appender;
/**
* 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);
appender = new InMemoryAppender();
}
/**
* Removed the mocked std-out {@link PrintStream} again from the {@link System} class
*/
@After
public void tearDown() {
System.setOut(this.stdOutOrig);
appender.stop();
}
/**
/**
* Test a complete day cycle in the gold mine by executing all three different steps: {@link
* DwarvenGoldmineFacade#startNewDay()}, {@link DwarvenGoldmineFacade#digOutGold()} and {@link
* DwarvenGoldmineFacade#endDay()}.
@ -82,44 +68,68 @@ public class DwarvenGoldmineFacadeTest {
goldMine.startNewDay();
// On the start of a day, all workers should wake up ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger wakes up."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator wakes up."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger wakes up."));
assertTrue(appender.logContains("Dwarf gold digger wakes up."));
assertTrue(appender.logContains("Dwarf cart operator wakes up."));
assertTrue(appender.logContains("Dwarven tunnel digger wakes up."));
// ... and go to the mine
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes to the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes to the mine."));
assertTrue(appender.logContains("Dwarf gold digger goes to the mine."));
assertTrue(appender.logContains("Dwarf cart operator goes to the mine."));
assertTrue(appender.logContains("Dwarven tunnel digger goes to the mine."));
// No other actions were invoked, so the workers shouldn't have done (printed) anything else
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(6, appender.getLogSize());
// Now do some actual work, start digging gold!
goldMine.digOutGold();
// Since we gave the dig command, every worker should be doing it's job ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger digs for gold."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator moves gold chunks out of the mine."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger creates another promising tunnel."));
assertTrue(appender.logContains("Dwarf gold digger digs for gold."));
assertTrue(appender.logContains("Dwarf cart operator moves gold chunks out of the mine."));
assertTrue(appender.logContains("Dwarven tunnel digger creates another promising tunnel."));
// Again, they shouldn't be doing anything else.
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(9, appender.getLogSize());
// Enough gold, lets end the day.
goldMine.endDay();
// Check if the workers go home ...
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes home."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes home."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes home."));
assertTrue(appender.logContains("Dwarf gold digger goes home."));
assertTrue(appender.logContains("Dwarf cart operator goes home."));
assertTrue(appender.logContains("Dwarven tunnel digger goes home."));
// ... and go to sleep. We need well rested workers the next day :)
verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes to sleep."));
verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to sleep."));
verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes to sleep."));
assertTrue(appender.logContains("Dwarf gold digger goes to sleep."));
assertTrue(appender.logContains("Dwarf cart operator goes to sleep."));
assertTrue(appender.logContains("Dwarven tunnel digger goes to sleep."));
// Every worker should be sleeping now, no other actions allowed
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(15, appender.getLogSize());
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
public boolean logContains(String message) {
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.factorykit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Factory-kit is a creational pattern which defines a factory of immutable content
* with separated builder and factory interfaces to deal with the problem of
@ -36,6 +39,9 @@ package com.iluwatar.factorykit;
* be mapped explicitly with desired class type in the factory instance.
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point.
*
@ -49,6 +55,6 @@ public class App {
builder.add(WeaponType.BOW, Bow::new);
});
Weapon axe = factory.create(WeaponType.AXE);
System.out.println(axe);
LOGGER.info(axe.toString());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.factory.method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The Factory Method is a creational design pattern which uses factory methods to deal with the
@ -38,6 +41,8 @@ package com.iluwatar.factory.method;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private final Blacksmith blacksmith;
/**
@ -70,8 +75,8 @@ public class App {
private void manufactureWeapons() {
Weapon weapon;
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
System.out.println(weapon);
LOGGER.info(weapon.toString());
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
System.out.println(weapon);
LOGGER.info(weapon.toString());
}
}

View File

@ -27,6 +27,8 @@ import com.iluwatar.featuretoggle.pattern.Service;
import com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion;
import com.iluwatar.featuretoggle.user.User;
import com.iluwatar.featuretoggle.user.UserGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
@ -45,6 +47,8 @@ import java.util.Properties;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Block 1 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature
* toggle to enabled.
@ -70,7 +74,7 @@ public class App {
properties.put("enhancedWelcome", true);
Service service = new PropertiesFeatureToggleVersion(properties);
final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code"));
System.out.println(welcomeMessage);
LOGGER.info(welcomeMessage);
// ---------------------------------------------
@ -78,7 +82,7 @@ public class App {
turnedOff.put("enhancedWelcome", false);
Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff);
final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code"));
System.out.println(welcomeMessageturnedOff);
LOGGER.info(welcomeMessageturnedOff);
// --------------------------------------------
@ -90,7 +94,7 @@ public class App {
final String welcomeMessagePaidUser = service.getWelcomeMessage(paidUser);
final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser);
System.out.println(welcomeMessageFreeUser);
System.out.println(welcomeMessagePaidUser);
LOGGER.info(welcomeMessageFreeUser);
LOGGER.info(welcomeMessagePaidUser);
}
}

View File

@ -35,6 +35,8 @@ 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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API.
@ -50,6 +52,8 @@ import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*/
@ -74,9 +78,7 @@ public class App {
.fromCopyOf(integerList)
.filter(number -> number % 2 == 0)
.first()
.ifPresent(
evenNumber -> System.out.println(String.format("The first even number is: %d",
evenNumber)));
.ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber));
List<String> transformedList =
@ -97,9 +99,7 @@ public class App {
.filter(negatives())
.first(2)
.last()
.ifPresent(
lastOfFirstTwo -> System.out.println(String.format(
"The last of the first two negatives is: %d", lastOfFirstTwo)));
.ifPresent(lastOfFirstTwo -> LOGGER.info("The last of the first two negatives is: {}", lastOfFirstTwo));
}
private static Function<Integer, String> transformToString() {
@ -126,6 +126,6 @@ public class App {
joiner.add(iterator.next().toString());
}
System.out.println(joiner);
LOGGER.info(joiner.toString());
}
}

View File

@ -25,6 +25,8 @@ package com.iluwatar.flux.view;
import com.iluwatar.flux.action.Content;
import com.iluwatar.flux.store.ContentStore;
import com.iluwatar.flux.store.Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
@ -33,6 +35,8 @@ import com.iluwatar.flux.store.Store;
*/
public class ContentView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ContentView.class);
private Content content = Content.PRODUCTS;
@Override
@ -44,6 +48,6 @@ public class ContentView implements View {
@Override
public void render() {
System.out.println(content.toString());
LOGGER.info(content.toString());
}
}

View File

@ -26,6 +26,8 @@ import com.iluwatar.flux.action.MenuItem;
import com.iluwatar.flux.dispatcher.Dispatcher;
import com.iluwatar.flux.store.MenuStore;
import com.iluwatar.flux.store.Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
@ -34,6 +36,8 @@ import com.iluwatar.flux.store.Store;
*/
public class MenuView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(MenuView.class);
private MenuItem selected = MenuItem.HOME;
@Override
@ -47,9 +51,9 @@ public class MenuView implements View {
public void render() {
for (MenuItem item : MenuItem.values()) {
if (selected.equals(item)) {
System.out.println(String.format("* %s", item.toString()));
LOGGER.info("* {}", item);
} else {
System.out.println(item.toString());
LOGGER.info(item.toString());
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -33,6 +36,8 @@ import java.util.List;
*/
public class AlchemistShop {
private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class);
private List<Potion> topShelf;
private List<Potion> bottomShelf;
@ -88,13 +93,13 @@ public class AlchemistShop {
*/
public void enumerate() {
System.out.println("Enumerating top shelf potions\n");
LOGGER.info("Enumerating top shelf potions\n");
for (Potion p : topShelf) {
p.drink();
}
System.out.println("\nEnumerating bottom shelf potions\n");
LOGGER.info("Enumerating bottom shelf potions\n");
for (Potion p : bottomShelf) {
p.drink();

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* HealingPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/
public class HealingPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(HealingPotion.class);
@Override
public void drink() {
System.out.println("You feel healed. (Potion=" + System.identityHashCode(this) + ")");
LOGGER.info("You feel healed. (Potion={})", System.identityHashCode(this));
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* HolyWaterPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/
public class HolyWaterPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(HolyWaterPotion.class);
@Override
public void drink() {
System.out.println("You feel blessed. (Potion=" + System.identityHashCode(this) + ")");
LOGGER.info("You feel blessed. (Potion={})", System.identityHashCode(this));
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* InvisibilityPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/
public class InvisibilityPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(InvisibilityPotion.class);
@Override
public void drink() {
System.out.println("You become invisible. (Potion=" + System.identityHashCode(this) + ")");
LOGGER.info("You become invisible. (Potion={})", System.identityHashCode(this));
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* PoisonPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/
public class PoisonPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(PoisonPotion.class);
@Override
public void drink() {
System.out.println("Urgh! This is poisonous. (Potion=" + System.identityHashCode(this) + ")");
LOGGER.info("Urgh! This is poisonous. (Potion={})", System.identityHashCode(this));
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.flyweight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* StrengthPotion
@ -29,8 +32,10 @@ package com.iluwatar.flyweight;
*/
public class StrengthPotion implements Potion {
private static final Logger LOGGER = LoggerFactory.getLogger(StrengthPotion.class);
@Override
public void drink() {
System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")");
LOGGER.info("You feel strong. (Potion={})", System.identityHashCode(this));
}
}

View File

@ -22,15 +22,20 @@
*/
package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* View for archers.
*
*/
public class ArcherView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ArcherView.class);
@Override
public void display() {
System.out.println("Displaying archers");
LOGGER.info("Displaying archers");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* View for catapults.
@ -29,8 +32,10 @@ package com.iluwatar.front.controller;
*/
public class CatapultView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(CatapultView.class);
@Override
public void display() {
System.out.println("Displaying catapults");
LOGGER.info("Displaying catapults");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.front.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* View for errors.
@ -29,8 +32,10 @@ package com.iluwatar.front.controller;
*/
public class ErrorView implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(ErrorView.class);
@Override
public void display() {
System.out.println("Error 500");
LOGGER.error("Error 500");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class CommandTest extends StdOutTest {
public class CommandTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters
public static List<Object[]> data() {
@ -75,10 +88,10 @@ public class CommandTest extends StdOutTest {
@Test
public void testDisplay() {
final FrontController frontController = new FrontController();
verifyZeroInteractions(getStdOutMock());
assertEquals(0, appender.getLogSize());
frontController.handleRequest(request);
verify(getStdOutMock()).println(displayMessage);
verifyNoMoreInteractions(getStdOutMock());
assertEquals(displayMessage, appender.getLastMessage());
assertEquals(1, appender.getLogSize());
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class FrontControllerTest extends StdOutTest {
public class FrontControllerTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters
public static List<Object[]> data() {
@ -74,10 +87,10 @@ public class FrontControllerTest extends StdOutTest {
@Test
public void testDisplay() {
verifyZeroInteractions(getStdOutMock());
assertEquals(0, appender.getLogSize());
this.command.process();
verify(getStdOutMock()).println(displayMessage);
verifyNoMoreInteractions(getStdOutMock());
assertEquals(displayMessage, appender.getLastMessage());
assertEquals(1, appender.getLogSize());
}
}

View File

@ -1,76 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.front.controller;
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;
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.front.controller;
import com.iluwatar.front.controller.utils.InMemoryAppender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.junit.Assert.assertEquals;
/**
* Date: 12/13/15 - 1:39 PM
@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* @author Jeroen Meulemeester
*/
@RunWith(Parameterized.class)
public class ViewTest extends StdOutTest {
public class ViewTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender();
}
@After
public void tearDown() {
appender.stop();
}
@Parameters
public static List<Object[]> data() {
@ -74,10 +87,10 @@ public class ViewTest extends StdOutTest {
@Test
public void testDisplay() {
verifyZeroInteractions(getStdOutMock());
assertEquals(0, appender.getLogSize());
this.view.display();
verify(getStdOutMock()).println(displayMessage);
verifyNoMoreInteractions(getStdOutMock());
assertEquals(displayMessage, appender.getLastMessage());
assertEquals(1, appender.getLogSize());
}
}
}

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.front.controller.utils;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender() {
((Logger) LoggerFactory.getLogger("root")).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.halfsynchalfasync;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue;
/**
@ -66,6 +69,8 @@ import java.util.concurrent.LinkedBlockingQueue;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -128,7 +133,7 @@ public class App {
@Override
public void onPostCall(Long result) {
// Handle the result of computation
System.out.println(result);
LOGGER.info(result.toString());
}
@Override
@ -141,7 +146,7 @@ public class App {
try {
Thread.sleep(i);
} catch (InterruptedException e) {
System.out.println(e);
LOGGER.error("Exception caught.", e);
}
return i * (i + 1) / 2;
}

View File

@ -30,6 +30,8 @@ import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
import com.iluwatar.hexagonal.sampledata.SampleData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Scanner;
@ -38,6 +40,8 @@ import java.util.Scanner;
*/
public class ConsoleAdministration {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleAdministration.class);
/**
* Program entry point
*/
@ -53,29 +57,29 @@ public class ConsoleAdministration {
printMainMenu();
String cmd = readString(scanner);
if (cmd.equals("1")) {
administartion.getAllSubmittedTickets().forEach((k,v)->System.out.println("Key: " + k + " Value: " + v));
administartion.getAllSubmittedTickets().forEach((k,v)->LOGGER.info("Key: {}, Value: {}", k, v));
} else if (cmd.equals("2")) {
LotteryNumbers numbers = administartion.performLottery();
System.out.println("The winning numbers: " + numbers.getNumbersAsString());
System.out.println("Time to reset the database for next round, eh?");
LOGGER.info("The winning numbers: {}", numbers.getNumbersAsString());
LOGGER.info("Time to reset the database for next round, eh?");
} else if (cmd.equals("3")) {
administartion.resetLottery();
System.out.println("The lottery ticket database was cleared.");
LOGGER.info("The lottery ticket database was cleared.");
} else if (cmd.equals("4")) {
exit = true;
} else {
System.out.println("Unknown command: " + cmd);
LOGGER.info("Unknown command: {}", cmd);
}
}
}
private static void printMainMenu() {
System.out.println("");
System.out.println("### Lottery Administration Console ###");
System.out.println("(1) Show all submitted tickets");
System.out.println("(2) Perform lottery draw");
System.out.println("(3) Reset lottery ticket database");
System.out.println("(4) Exit");
LOGGER.info("");
LOGGER.info("### Lottery Administration Console ###");
LOGGER.info("(1) Show all submitted tickets");
LOGGER.info("(2) Perform lottery draw");
LOGGER.info("(3) Reset lottery ticket database");
LOGGER.info("(4) Exit");
}
private static String readString(Scanner scanner) {

View File

@ -23,42 +23,42 @@
package com.iluwatar.hexagonal.eventlog;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Standard output event log
*/
public class StdOutEventLog implements LotteryEventLog {
private static final Logger LOGGER = LoggerFactory.getLogger(StdOutEventLog.class);
@Override
public void ticketSubmitted(PlayerDetails details) {
System.out.println(String.format("Lottery ticket for %s was submitted. Bank account %s was charged for 3 credits.",
details.getEmail(), details.getBankAccount()));
LOGGER.info("Lottery ticket for {} was submitted. Bank account {} was charged for 3 credits.",
details.getEmail(), details.getBankAccount());
}
@Override
public void ticketDidNotWin(PlayerDetails details) {
System.out.println(String.format("Lottery ticket for %s was checked and unfortunately did not win this time.",
details.getEmail()));
LOGGER.info("Lottery ticket for {} was checked and unfortunately did not win this time.", details.getEmail());
}
@Override
public void ticketWon(PlayerDetails details, int prizeAmount) {
System.out
.println(String.format("Lottery ticket for %s has won! The bank account %s was deposited with %d credits.",
details.getEmail(), details.getBankAccount(), prizeAmount));
LOGGER.info("Lottery ticket for {} has won! The bank account {} was deposited with {} credits.",
details.getEmail(), details.getBankAccount(), prizeAmount);
}
@Override
public void prizeError(PlayerDetails details, int prizeAmount) {
System.out
.println(String.format("Lottery ticket for %s has won! Unfortunately the bank credit transfer of %d failed.",
details.getEmail(), prizeAmount));
LOGGER.error("Lottery ticket for {} has won! Unfortunately the bank credit transfer of {} failed.",
details.getEmail(), prizeAmount);
}
@Override
public void ticketSubmitError(PlayerDetails details) {
System.out.println(
String.format("Lottery ticket for %s could not be submitted because the credit transfer of 3 credits failed.",
details.getEmail()));
LOGGER.error("Lottery ticket for {} could not be submitted because the credit transfer of 3 credits failed.",
details.getEmail());
}
}

View File

@ -33,6 +33,8 @@ import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.Optional;
@ -44,6 +46,7 @@ import java.util.Set;
*/
public class ConsoleLottery {
private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleLottery.class);
/**
* Program entry point
@ -59,25 +62,25 @@ public class ConsoleLottery {
printMainMenu();
String cmd = readString(scanner);
if (cmd.equals("1")) {
System.out.println("What is the account number?");
LOGGER.info("What is the account number?");
String account = readString(scanner);
System.out.println(String.format("The account %s has %d credits.", account, bank.getFunds(account)));
LOGGER.info("The account {} has {} credits.", account, bank.getFunds(account));
} else if (cmd.equals("2")) {
System.out.println("What is the account number?");
LOGGER.info("What is the account number?");
String account = readString(scanner);
System.out.println("How many credits do you want to deposit?");
LOGGER.info("How many credits do you want to deposit?");
String amount = readString(scanner);
bank.setFunds(account, Integer.parseInt(amount));
System.out.println(String.format("The account %s now has %d credits.", account, bank.getFunds(account)));
LOGGER.info("The account {} now has {} credits.", account, bank.getFunds(account));
} else if (cmd.equals("3")) {
System.out.println("What is your email address?");
LOGGER.info("What is your email address?");
String email = readString(scanner);
System.out.println("What is your bank account number?");
LOGGER.info("What is your bank account number?");
String account = readString(scanner);
System.out.println("What is your phone number?");
LOGGER.info("What is your phone number?");
String phone = readString(scanner);
PlayerDetails details = new PlayerDetails(email, account, phone);
System.out.println("Give 4 comma separated lottery numbers?");
LOGGER.info("Give 4 comma separated lottery numbers?");
String numbers = readString(scanner);
try {
String[] parts = numbers.split(",");
@ -89,17 +92,17 @@ public class ConsoleLottery {
LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers);
Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket);
if (id.isPresent()) {
System.out.println("Submitted lottery ticket with id: " + id.get());
LOGGER.info("Submitted lottery ticket with id: {}", id.get());
} else {
System.out.println("Failed submitting lottery ticket - please try again.");
LOGGER.info("Failed submitting lottery ticket - please try again.");
}
} catch (Exception e) {
System.out.println("Failed submitting lottery ticket - please try again.");
LOGGER.info("Failed submitting lottery ticket - please try again.");
}
} else if (cmd.equals("4")) {
System.out.println("What is the ID of the lottery ticket?");
LOGGER.info("What is the ID of the lottery ticket?");
String id = readString(scanner);
System.out.println("Give the 4 comma separated winning numbers?");
LOGGER.info("Give the 4 comma separated winning numbers?");
String numbers = readString(scanner);
try {
String[] parts = numbers.split(",");
@ -110,31 +113,31 @@ public class ConsoleLottery {
LotteryTicketCheckResult result = service.checkTicketForPrize(
new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers));
if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) {
System.out.println("Congratulations! The lottery ticket has won!");
LOGGER.info("Congratulations! The lottery ticket has won!");
} else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) {
System.out.println("Unfortunately the lottery ticket did not win.");
LOGGER.info("Unfortunately the lottery ticket did not win.");
} else {
System.out.println("Such lottery ticket has not been submitted.");
LOGGER.info("Such lottery ticket has not been submitted.");
}
} catch (Exception e) {
System.out.println("Failed checking the lottery ticket - please try again.");
LOGGER.info("Failed checking the lottery ticket - please try again.");
}
} else if (cmd.equals("5")) {
exit = true;
} else {
System.out.println("Unknown command");
LOGGER.info("Unknown command");
}
}
}
private static void printMainMenu() {
System.out.println("");
System.out.println("### Lottery Service Console ###");
System.out.println("(1) Query lottery account funds");
System.out.println("(2) Add funds to lottery account");
System.out.println("(3) Submit ticket");
System.out.println("(4) Check ticket");
System.out.println("(5) Exit");
LOGGER.info("");
LOGGER.info("### Lottery Service Console ###");
LOGGER.info("(1) Query lottery account funds");
LOGGER.info("(2) Add funds to lottery account");
LOGGER.info("(3) Submit ticket");
LOGGER.info("(4) Check ticket");
LOGGER.info("(5) Exit");
}
private static String readString(Scanner scanner) {

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.interpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Stack;
/**
@ -37,6 +40,8 @@ import java.util.Stack;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
*
* Program entry point.
@ -56,21 +61,21 @@ public class App {
if (isOperator(s)) {
Expression rightExpression = stack.pop();
Expression leftExpression = stack.pop();
System.out.println(String.format("popped from stack left: %d right: %d",
leftExpression.interpret(), rightExpression.interpret()));
LOGGER.info("popped from stack left: {} right: {}",
leftExpression.interpret(), rightExpression.interpret());
Expression operator = getOperatorInstance(s, leftExpression, rightExpression);
System.out.println(String.format("operator: %s", operator));
LOGGER.info("operator: {}", operator);
int result = operator.interpret();
NumberExpression resultExpression = new NumberExpression(result);
stack.push(resultExpression);
System.out.println(String.format("push result to stack: %d", resultExpression.interpret()));
LOGGER.info("push result to stack: {}", resultExpression.interpret());
} else {
Expression i = new NumberExpression(s);
stack.push(i);
System.out.println(String.format("push to stack: %d", i.interpret()));
LOGGER.info("push to stack: {}", i.interpret());
}
}
System.out.println(String.format("result: %d", stack.pop().interpret()));
LOGGER.info("result: {}", stack.pop().interpret());
}
public static boolean isOperator(String s) {

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The Iterator pattern is a design pattern in which an iterator is used to traverse a container and
@ -34,6 +37,8 @@ package com.iluwatar.iterator;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -44,28 +49,28 @@ public class App {
ItemIterator ringIterator = chest.iterator(ItemType.RING);
while (ringIterator.hasNext()) {
System.out.println(ringIterator.next());
LOGGER.info(ringIterator.next().toString());
}
System.out.println("----------");
LOGGER.info("----------");
ItemIterator potionIterator = chest.iterator(ItemType.POTION);
while (potionIterator.hasNext()) {
System.out.println(potionIterator.next());
LOGGER.info(potionIterator.next().toString());
}
System.out.println("----------");
LOGGER.info("----------");
ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON);
while (weaponIterator.hasNext()) {
System.out.println(weaponIterator.next());
LOGGER.info(weaponIterator.next().toString());
}
System.out.println("----------");
LOGGER.info("----------");
ItemIterator it = chest.iterator(ItemType.ANY);
while (it.hasNext()) {
System.out.println(it.next());
LOGGER.info(it.next().toString());
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.layers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* View implementation for displaying cakes
@ -29,6 +32,8 @@ package com.iluwatar.layers;
*/
public class CakeViewImpl implements View {
private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class);
private CakeBakingService cakeBakingService;
public CakeViewImpl(CakeBakingService cakeBakingService) {
@ -36,6 +41,6 @@ public class CakeViewImpl implements View {
}
public void render() {
cakeBakingService.getAllCakes().stream().forEach(cake -> System.out.println(cake));
cakeBakingService.getAllCakes().stream().forEach(cake -> LOGGER.info(cake.toString()));
}
}

View File

@ -0,0 +1,57 @@
<!--
The MIT License
Copyright (c) 2014 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>layers.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>layers-%d.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5p [%d{ISO8601,UTC}] %c: %m%n</pattern>
</encoder>
</appender>
<logger name="com.iluwatar" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="FILE"/>
</logger>
<logger name="org.hibernate" additivity="false">
<level value="ERROR"/>
<appender-ref ref="STDOUT"/>
</logger>
<root level="WARN">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

View File

@ -22,11 +22,19 @@
*/
package com.iluwatar.layers;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
/**
@ -34,7 +42,19 @@ import static org.mockito.Mockito.*;
*
* @author Jeroen Meulemeester
*/
public class CakeViewImplTest extends StdOutTest {
public class CakeViewImplTest {
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(CakeViewImpl.class);
}
@After
public void tearDown() {
appender.stop();
}
/**
* Verify if the cake view renders the expected result
@ -56,11 +76,34 @@ public class CakeViewImplTest extends StdOutTest {
final CakeViewImpl cakeView = new CakeViewImpl(bakingService);
verifyZeroInteractions(getStdOutMock());
assertEquals(0, appender.getLogSize());
cakeView.render();
verify(getStdOutMock(), times(1)).println(cake);
assertEquals(cake.toString(), appender.getLastMessage());
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
public int getLogSize() {
return log.size();
}
}
}

View File

@ -1,76 +0,0 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
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;
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Lazy loading idiom defers object creation until needed.
@ -33,6 +36,9 @@ package com.iluwatar.lazy.loading;
*
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
@ -43,16 +49,16 @@ public class App {
// Simple lazy loader - not thread safe
HolderNaive holderNaive = new HolderNaive();
Heavy heavy = holderNaive.getHeavy();
System.out.println("heavy=" + heavy);
LOGGER.info("heavy={}", heavy);
// Thread safe lazy loader, but with heavy synchronization on each access
HolderThreadSafe holderThreadSafe = new HolderThreadSafe();
Heavy another = holderThreadSafe.getHeavy();
System.out.println("another=" + another);
LOGGER.info("another={}", another);
// The most efficient lazy loader utilizing Java 8 features
Java8Holder java8Holder = new Java8Holder();
Heavy next = java8Holder.getHeavy();
System.out.println("next=" + next);
LOGGER.info("next={}", next);
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Heavy objects are expensive to create.
@ -29,16 +32,18 @@ package com.iluwatar.lazy.loading;
*/
public class Heavy {
private static final Logger LOGGER = LoggerFactory.getLogger(Heavy.class);
/**
* Constructor
*/
public Heavy() {
System.out.println("Creating Heavy ...");
LOGGER.info("Creating Heavy ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
LOGGER.error("Exception caught.", e);
}
System.out.println("... Heavy created");
LOGGER.info("... Heavy created");
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Simple implementation of the lazy loading idiom. However, this is not thread safe.
@ -29,13 +32,15 @@ package com.iluwatar.lazy.loading;
*/
public class HolderNaive {
private static final Logger LOGGER = LoggerFactory.getLogger(HolderNaive.class);
private Heavy heavy;
/**
* Constructor
*/
public HolderNaive() {
System.out.println("HolderNaive created");
LOGGER.info("HolderNaive created");
}
/**

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Same as HolderNaive but with added synchronization. This implementation is thread safe, but each
@ -30,13 +33,15 @@ package com.iluwatar.lazy.loading;
*/
public class HolderThreadSafe {
private static final Logger LOGGER = LoggerFactory.getLogger(HolderThreadSafe.class);
private Heavy heavy;
/**
* Constructor
*/
public HolderThreadSafe() {
System.out.println("HolderThreadSafe created");
LOGGER.info("HolderThreadSafe created");
}
/**

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.lazy.loading;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier;
/**
@ -32,10 +35,12 @@ import java.util.function.Supplier;
*/
public class Java8Holder {
private static final Logger LOGGER = LoggerFactory.getLogger(Java8Holder.class);
private Supplier<Heavy> heavy = () -> createAndCacheHeavy();
public Java8Holder() {
System.out.println("Java8Holder created");
LOGGER.info("Java8Holder created");
}
public Heavy getHeavy() {

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.mediator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Abstract base class for party members.
@ -29,23 +32,25 @@ package com.iluwatar.mediator;
*/
public abstract class PartyMemberBase implements PartyMember {
private static final Logger LOGGER = LoggerFactory.getLogger(PartyMemberBase.class);
protected Party party;
@Override
public void joinedParty(Party party) {
System.out.println(this + " joins the party");
LOGGER.info("{} joins the party", this);
this.party = party;
}
@Override
public void partyAction(Action action) {
System.out.println(this + " " + action.getDescription());
LOGGER.info("{} {}", this, action.getDescription());
}
@Override
public void act(Action action) {
if (party != null) {
System.out.println(this + " " + action.toString());
LOGGER.info("{} {}", this, action);
party.act(this, action);
}
}

View File

@ -22,22 +22,25 @@
*/
package com.iluwatar.mediator;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
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
@ -57,34 +60,6 @@ public class PartyMemberTest {
);
}
/**
* 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
*/
@ -99,6 +74,18 @@ public class PartyMemberTest {
this.memberSupplier = memberSupplier;
}
private InMemoryAppender appender;
@Before
public void setUp() {
appender = new InMemoryAppender(PartyMemberBase.class);
}
@After
public void tearDown() {
appender.stop();
}
/**
* Verify if a party action triggers the correct output to the std-Out
*/
@ -108,10 +95,10 @@ public class PartyMemberTest {
for (final Action action : Action.values()) {
member.partyAction(action);
verify(this.stdOutMock).println(member.toString() + " " + action.getDescription());
assertEquals(member.toString() + " " + action.getDescription(), appender.getLastMessage());
}
verifyNoMoreInteractions(this.stdOutMock);
assertEquals(Action.values().length, appender.getLogSize());
}
/**
@ -122,19 +109,19 @@ public class PartyMemberTest {
final PartyMember member = this.memberSupplier.get();
member.act(Action.GOLD);
verifyZeroInteractions(this.stdOutMock);
assertEquals(0, appender.getLogSize());
final Party party = mock(Party.class);
member.joinedParty(party);
verify(this.stdOutMock).println(member.toString() + " joins the party");
assertEquals(member.toString() + " joins the party", appender.getLastMessage());
for (final Action action : Action.values()) {
member.act(action);
verify(this.stdOutMock).println(member.toString() + " " + action.toString());
assertEquals(member.toString() + " " + action.toString(), appender.getLastMessage());
verify(party).act(member, action);
}
verifyNoMoreInteractions(party, this.stdOutMock);
assertEquals(Action.values().length + 1, appender.getLogSize());
}
/**
@ -147,4 +134,27 @@ public class PartyMemberTest {
assertEquals(memberClass.getSimpleName(), member.toString());
}
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
private List<ILoggingEvent> log = new LinkedList<>();
public InMemoryAppender(Class clazz) {
((Logger) LoggerFactory.getLogger(clazz)).addAppender(this);
start();
}
@Override
protected void append(ILoggingEvent eventObject) {
log.add(eventObject);
}
public int getLogSize() {
return log.size();
}
public String getLastMessage() {
return log.get(log.size() - 1).getFormattedMessage();
}
}
}

View File

@ -22,6 +22,9 @@
*/
package com.iluwatar.memento;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Stack;
/**
@ -45,6 +48,8 @@ import java.util.Stack;
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*/
@ -52,22 +57,22 @@ public class App {
Stack<StarMemento> states = new Stack<>();
Star star = new Star(StarType.SUN, 10000000, 500000);
System.out.println(star);
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
System.out.println(star);
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
System.out.println(star);
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
System.out.println(star);
LOGGER.info(star.toString());
states.add(star.getMemento());
star.timePasses();
System.out.println(star);
LOGGER.info(star.toString());
while (states.size() > 0) {
star.setMemento(states.pop());
System.out.println(star);
LOGGER.info(star.toString());
}
}
}

Some files were not shown because too many files have changed in this diff Show More