Merge pull request #515 from dbryla/master
#502 Added logging framework to repository
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,5 +15,5 @@ datanucleus.log | ||||
| /bin/ | ||||
| /bin/ | ||||
| /bin/ | ||||
|  | ||||
| *.log | ||||
| data-mapper/src/main/resources/log4j.xml | ||||
| @@ -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())); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -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()); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 ..."); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|  | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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."); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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!"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -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); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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,11 +64,12 @@ 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()); | ||||
|     } | ||||
|     assertEquals(tobaccos.length, appender.getLogSize()); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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; | ||||
|   } | ||||
| } | ||||
| @@ -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(); | ||||
|   } | ||||
| } | ||||
| @@ -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"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
							
								
								
									
										52
									
								
								double-checked-locking/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								double-checked-locking/src/main/resources/logback.xml
									
									
									
									
									
										Normal 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> | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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(""); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -16,6 +16,9 @@ | ||||
|  */ | ||||
| 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; | ||||
| @@ -48,6 +51,8 @@ import java.util.Scanner; | ||||
|  */ | ||||
| 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(); | ||||
|   | ||||
| @@ -16,6 +16,9 @@ | ||||
|  */ | ||||
| package com.iluwatar.event.asynchronous; | ||||
|  | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Each Event runs as a separate/individual thread. | ||||
| @@ -23,6 +26,8 @@ package com.iluwatar.event.asynchronous; | ||||
|  */ | ||||
| public class Event implements IEvent, Runnable { | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(Event.class); | ||||
|  | ||||
|   private int eventId; | ||||
|   private int eventTime; | ||||
|   private boolean isSynchronous; | ||||
| @@ -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); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,32 +43,16 @@ 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(); | ||||
|   } | ||||
|  | ||||
|    /** | ||||
| @@ -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)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,9 @@ | ||||
|  */ | ||||
| package com.iluwatar.front.controller; | ||||
|  | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * View for archers. | ||||
| @@ -29,8 +32,10 @@ package com.iluwatar.front.controller; | ||||
|  */ | ||||
| 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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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()); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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(); | ||||
|   } | ||||
| } | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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())); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										57
									
								
								layers/src/main/resources/logback.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								layers/src/main/resources/logback.xml
									
									
									
									
									
										Normal 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> | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -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"); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -25,6 +25,8 @@ package com.iluwatar.message.channel; | ||||
| import org.apache.camel.CamelContext; | ||||
| import org.apache.camel.builder.RouteBuilder; | ||||
| import org.apache.camel.impl.DefaultCamelContext; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
| @@ -50,6 +52,8 @@ import org.apache.camel.impl.DefaultCamelContext; | ||||
|  */ | ||||
| public class App { | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||
|  | ||||
|   /** | ||||
|    * Program entry point | ||||
|    */ | ||||
| @@ -66,7 +70,7 @@ public class App { | ||||
|     }); | ||||
|  | ||||
|     context.start(); | ||||
|     context.getRoutes().stream().forEach(r -> System.out.println(r)); | ||||
|     context.getRoutes().stream().forEach(r -> LOGGER.info(r.toString())); | ||||
|     context.stop(); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,9 @@ | ||||
|  */ | ||||
| package com.iluwatar.model.view.controller; | ||||
|  | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * GiantView displays the giant | ||||
| @@ -29,7 +32,9 @@ package com.iluwatar.model.view.controller; | ||||
|  */ | ||||
| public class GiantView { | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(GiantView.class); | ||||
|  | ||||
|   public void displayGiant(GiantModel giant) { | ||||
|     System.out.println(giant); | ||||
|     LOGGER.info(giant.toString()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -22,15 +22,19 @@ | ||||
|  */ | ||||
| package com.iluwatar.model.view.controller; | ||||
|  | ||||
| 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.Mockito.mock; | ||||
| import static org.mockito.Mockito.verify; | ||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
|  | ||||
| /** | ||||
|  * Date: 12/20/15 - 2:04 PM | ||||
| @@ -39,32 +43,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
|  */ | ||||
| public class GiantViewTest { | ||||
|  | ||||
|   /** | ||||
|    * The mocked standard out {@link PrintStream}, required since the actions of the views don't have | ||||
|    * any influence on any other accessible objects, except for writing to std-out using {@link | ||||
|    * System#out} | ||||
|    */ | ||||
|   private final PrintStream stdOutMock = mock(PrintStream.class); | ||||
|   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(GiantView.class); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Removed the mocked std-out {@link PrintStream} again from the {@link System} class | ||||
|    */ | ||||
|   @After | ||||
|   public void tearDown() { | ||||
|     System.setOut(this.stdOutOrig); | ||||
|     appender.stop(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
| @@ -78,9 +66,29 @@ public class GiantViewTest { | ||||
|     final GiantModel model = mock(GiantModel.class); | ||||
|     view.displayGiant(model); | ||||
|  | ||||
|     verify(this.stdOutMock).println(model); | ||||
|     verifyNoMoreInteractions(model, this.stdOutMock); | ||||
|  | ||||
|     assertEquals(model.toString(), appender.getLastMessage()); | ||||
|     assertEquals(1, appender.getLogSize()); | ||||
|   } | ||||
|  | ||||
|   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).getMessage(); | ||||
|     } | ||||
|  | ||||
|     public int getLogSize() { | ||||
|       return log.size(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -22,6 +22,9 @@ | ||||
|  */ | ||||
| package com.iluwatar.monad; | ||||
|  | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.util.Objects; | ||||
| import java.util.function.Function; | ||||
| import java.util.function.Predicate; | ||||
| @@ -42,6 +45,8 @@ import java.util.function.Predicate; | ||||
|  */ | ||||
| public class App { | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||
|  | ||||
|   /** | ||||
|    * Program entry point. | ||||
|    * | ||||
| @@ -49,7 +54,7 @@ public class App { | ||||
|    */ | ||||
|   public static void main(String[] args) { | ||||
|     User user = new User("user", 24, Sex.FEMALE, "foobar.com"); | ||||
|     System.out.println(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null") | ||||
|     LOGGER.info(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null") | ||||
|         .validate(User::getName, name -> !name.isEmpty(), "name is empty") | ||||
|         .validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'") | ||||
|         .validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get().toString()); | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user