Merge pull request #515 from dbryla/master
#502 Added logging framework to repository
This commit is contained in:
		
							
								
								
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,19 +1,19 @@ | |||||||
| target | target | ||||||
| .metadata | .metadata | ||||||
| .settings | .settings | ||||||
| .classpath | .classpath | ||||||
| .project | .project | ||||||
| *.class | *.class | ||||||
| # Package Files # | # Package Files # | ||||||
| *.jar | *.jar | ||||||
| *.war | *.war | ||||||
| *.ear | *.ear | ||||||
| .idea | .idea | ||||||
| *.iml | *.iml | ||||||
| *.swp | *.swp | ||||||
| datanucleus.log | datanucleus.log | ||||||
| /bin/ | /bin/ | ||||||
| /bin/ | /bin/ | ||||||
| /bin/ | /bin/ | ||||||
|  | *.log | ||||||
| data-mapper/src/main/resources/log4j.xml | 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.HasParts; | ||||||
| import com.iluwatar.abstractdocument.domain.HasPrice; | import com.iluwatar.abstractdocument.domain.HasPrice; | ||||||
| import com.iluwatar.abstractdocument.domain.HasType; | import com.iluwatar.abstractdocument.domain.HasType; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| @@ -44,11 +46,13 @@ import java.util.Map; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Executes the App |    * Executes the App | ||||||
|    */ |    */ | ||||||
|   public App() { |   public App() { | ||||||
|     System.out.println("Constructing parts and car"); |     LOGGER.info("Constructing parts and car"); | ||||||
|  |  | ||||||
|     Map<String, Object> carProperties = new HashMap<>(); |     Map<String, Object> carProperties = new HashMap<>(); | ||||||
|     carProperties.put(HasModel.PROPERTY, "300SL"); |     carProperties.put(HasModel.PROPERTY, "300SL"); | ||||||
| @@ -68,12 +72,11 @@ public class App { | |||||||
|  |  | ||||||
|     Car car = new Car(carProperties); |     Car car = new Car(carProperties); | ||||||
|  |  | ||||||
|     System.out.println("Here is our car:"); |     LOGGER.info("Here is our car:"); | ||||||
|     System.out.println("-> model: " + car.getModel().get()); |     LOGGER.info("-> model: {}", car.getModel().get()); | ||||||
|     System.out.println("-> price: " + car.getPrice().get()); |     LOGGER.info("-> price: {}", car.getPrice().get()); | ||||||
|     System.out.println("-> parts: "); |     LOGGER.info("-> parts: "); | ||||||
|     car.getParts().forEach(p -> System.out |     car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", p.getType().get(), p.getModel().get(), p.getPrice().get())); | ||||||
|         .println("\t" + p.getType().get() + "/" + p.getModel().get() + "/" + p.getPrice().get())); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.abstractfactory; | 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 |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   private King king; |   private King king; | ||||||
|   private Castle castle; |   private Castle castle; | ||||||
|   private Army army; |   private Army army; | ||||||
| @@ -98,17 +103,17 @@ public class App { | |||||||
|  |  | ||||||
|     App app = new App(); |     App app = new App(); | ||||||
|  |  | ||||||
|     System.out.println("Elf Kingdom"); |     LOGGER.info("Elf Kingdom"); | ||||||
|     app.createKingdom(new ElfKingdomFactory()); |     app.createKingdom(new ElfKingdomFactory()); | ||||||
|     System.out.println(app.getArmy().getDescription()); |     LOGGER.info(app.getArmy().getDescription()); | ||||||
|     System.out.println(app.getCastle().getDescription()); |     LOGGER.info(app.getCastle().getDescription()); | ||||||
|     System.out.println(app.getKing().getDescription()); |     LOGGER.info(app.getKing().getDescription()); | ||||||
|  |  | ||||||
|     System.out.println("\nOrc Kingdom"); |     LOGGER.info("Orc Kingdom"); | ||||||
|     app.createKingdom(new OrcKingdomFactory()); |     app.createKingdom(new OrcKingdomFactory()); | ||||||
|     System.out.println(app.getArmy().getDescription()); |     LOGGER.info(app.getArmy().getDescription()); | ||||||
|     System.out.println(app.getCastle().getDescription()); |     LOGGER.info(app.getCastle().getDescription()); | ||||||
|     System.out.println(app.getKing().getDescription()); |     LOGGER.info(app.getKing().getDescription()); | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.adapter; | 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} |  * 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 { | public class BattleFishingBoat implements BattleShip { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(BattleFishingBoat.class); | ||||||
|  |  | ||||||
|   private FishingBoat boat; |   private FishingBoat boat; | ||||||
|  |  | ||||||
|   public BattleFishingBoat() { |   public BattleFishingBoat() { | ||||||
| @@ -41,7 +46,7 @@ public class BattleFishingBoat implements BattleShip { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void fire() { |   public void fire() { | ||||||
|     System.out.println("fire!"); |     LOGGER.info("fire!"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.adapter; | package com.iluwatar.adapter; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * |  * | ||||||
|  * Device class (adaptee in the pattern). We want to reuse this class |  * Device class (adaptee in the pattern). We want to reuse this class | ||||||
| @@ -29,12 +32,14 @@ package com.iluwatar.adapter; | |||||||
|  */ |  */ | ||||||
| public class FishingBoat { | public class FishingBoat { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class); | ||||||
|  |  | ||||||
|   public void sail() { |   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() { |   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.CloseableHttpClient; | ||||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||||
| import org.apache.http.util.EntityUtils; | import org.apache.http.util.EntityUtils; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| @@ -37,6 +39,8 @@ import java.io.IOException; | |||||||
| @Component | @Component | ||||||
| public class ProductInformationClientImpl implements ProductInformationClient { | public class ProductInformationClientImpl implements ProductInformationClient { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ProductInformationClientImpl.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public String getProductTitle() { |   public String getProductTitle() { | ||||||
|     String response = null; |     String response = null; | ||||||
| @@ -46,7 +50,7 @@ public class ProductInformationClientImpl implements ProductInformationClient { | |||||||
|         response = EntityUtils.toString(httpResponse.getEntity()); |         response = EntityUtils.toString(httpResponse.getEntity()); | ||||||
|       } |       } | ||||||
|     } catch (IOException e) { |     } catch (IOException e) { | ||||||
|       e.printStackTrace(); |       LOGGER.error("Exception caught.", e); | ||||||
|     } |     } | ||||||
|     return response; |     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.CloseableHttpClient; | ||||||
| import org.apache.http.impl.client.HttpClients; | import org.apache.http.impl.client.HttpClients; | ||||||
| import org.apache.http.util.EntityUtils; | import org.apache.http.util.EntityUtils; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| @@ -37,6 +39,8 @@ import java.io.IOException; | |||||||
| @Component | @Component | ||||||
| public class ProductInventoryClientImpl implements ProductInventoryClient { | public class ProductInventoryClientImpl implements ProductInventoryClient { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ProductInventoryClientImpl.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public int getProductInventories() { |   public int getProductInventories() { | ||||||
|     String response = "0"; |     String response = "0"; | ||||||
| @@ -46,7 +50,7 @@ public class ProductInventoryClientImpl implements ProductInventoryClient { | |||||||
|         response = EntityUtils.toString(httpResponse.getEntity()); |         response = EntityUtils.toString(httpResponse.getEntity()); | ||||||
|       } |       } | ||||||
|     } catch (IOException e) { |     } catch (IOException e) { | ||||||
|       e.printStackTrace(); |       LOGGER.error("Exception caught.", e); | ||||||
|     } |     } | ||||||
|     return Integer.parseInt(response); |     return Integer.parseInt(response); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.async.method.invocation; | package com.iluwatar.async.method.invocation; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.concurrent.Callable; | import java.util.concurrent.Callable; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -54,6 +57,8 @@ import java.util.concurrent.Callable; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
| @@ -120,6 +125,6 @@ public class App { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static void log(String msg) { |   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; | package com.iluwatar.bridge; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Excalibur |  * Excalibur | ||||||
| @@ -29,23 +32,25 @@ package com.iluwatar.bridge; | |||||||
|  */ |  */ | ||||||
| public class Excalibur extends BlindingMagicWeaponImpl { | public class Excalibur extends BlindingMagicWeaponImpl { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Excalibur.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void wieldImp() { |   public void wieldImp() { | ||||||
|     System.out.println("wielding Excalibur"); |     LOGGER.info("wielding Excalibur"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void swingImp() { |   public void swingImp() { | ||||||
|     System.out.println("swinging Excalibur"); |     LOGGER.info("swinging Excalibur"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void unwieldImp() { |   public void unwieldImp() { | ||||||
|     System.out.println("unwielding Excalibur"); |     LOGGER.info("unwielding Excalibur"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void blindImp() { |   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; | package com.iluwatar.bridge; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Mjollnir |  * Mjollnir | ||||||
| @@ -29,23 +32,25 @@ package com.iluwatar.bridge; | |||||||
|  */ |  */ | ||||||
| public class Mjollnir extends FlyingMagicWeaponImpl { | public class Mjollnir extends FlyingMagicWeaponImpl { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void wieldImp() { |   public void wieldImp() { | ||||||
|     System.out.println("wielding Mjollnir"); |     LOGGER.info("wielding Mjollnir"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void swingImp() { |   public void swingImp() { | ||||||
|     System.out.println("swinging Mjollnir"); |     LOGGER.info("swinging Mjollnir"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void unwieldImp() { |   public void unwieldImp() { | ||||||
|     System.out.println("unwielding Mjollnir"); |     LOGGER.info("unwielding Mjollnir"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void flyImp() { |   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; | package com.iluwatar.bridge; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Stormbringer |  * Stormbringer | ||||||
| @@ -29,23 +32,25 @@ package com.iluwatar.bridge; | |||||||
|  */ |  */ | ||||||
| public class Stormbringer extends SoulEatingMagicWeaponImpl { | public class Stormbringer extends SoulEatingMagicWeaponImpl { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Stormbringer.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void wieldImp() { |   public void wieldImp() { | ||||||
|     System.out.println("wielding Stormbringer"); |     LOGGER.info("wielding Stormbringer"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void swingImp() { |   public void swingImp() { | ||||||
|     System.out.println("swinging Stormbringer"); |     LOGGER.info("swinging Stormbringer"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void unwieldImp() { |   public void unwieldImp() { | ||||||
|     System.out.println("unwielding Stormbringer"); |     LOGGER.info("unwielding Stormbringer"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void eatSoulImp() { |   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; | package com.iluwatar.builder; | ||||||
|  |  | ||||||
| import com.iluwatar.builder.Hero.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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -60,18 +64,18 @@ public class App { | |||||||
|     Hero mage = |     Hero mage = | ||||||
|         new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK) |         new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK) | ||||||
|             .withWeapon(Weapon.DAGGER).build(); |             .withWeapon(Weapon.DAGGER).build(); | ||||||
|     System.out.println(mage); |     LOGGER.info(mage.toString()); | ||||||
|  |  | ||||||
|     Hero warrior = |     Hero warrior = | ||||||
|         new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND) |         new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND) | ||||||
|             .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD) |             .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD) | ||||||
|             .build(); |             .build(); | ||||||
|     System.out.println(warrior); |     LOGGER.info(warrior.toString()); | ||||||
|  |  | ||||||
|     Hero thief = |     Hero thief = | ||||||
|         new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD) |         new Hero.Builder(Profession.THIEF, "Desmond").withHairType(HairType.BALD) | ||||||
|             .withWeapon(Weapon.BOW).build(); |             .withWeapon(Weapon.BOW).build(); | ||||||
|     System.out.println(thief); |     LOGGER.info(thief.toString()); | ||||||
|  |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.business.delegate; | package com.iluwatar.business.delegate; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Service EJB implementation |  * Service EJB implementation | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.business.delegate; | |||||||
|  */ |  */ | ||||||
| public class EjbService implements BusinessService { | public class EjbService implements BusinessService { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(EjbService.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void doProcessing() { |   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; | package com.iluwatar.business.delegate; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Service JMS implementation |  * Service JMS implementation | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.business.delegate; | |||||||
|  */ |  */ | ||||||
| public class JmsService implements BusinessService { | public class JmsService implements BusinessService { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(JmsService.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void doProcessing() { |   public void doProcessing() { | ||||||
|     System.out.println("JmsService is now processing"); |     LOGGER.info("JmsService is now processing"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.caching; | 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 |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    * |    * | ||||||
| @@ -82,13 +88,13 @@ public class App { | |||||||
|    * Read-through and write-through |    * Read-through and write-through | ||||||
|    */ |    */ | ||||||
|   public void useReadAndWriteThroughStrategy() { |   public void useReadAndWriteThroughStrategy() { | ||||||
|     System.out.println("# CachingPolicy.THROUGH"); |     LOGGER.info("# CachingPolicy.THROUGH"); | ||||||
|     AppManager.initCachingPolicy(CachingPolicy.THROUGH); |     AppManager.initCachingPolicy(CachingPolicy.THROUGH); | ||||||
|  |  | ||||||
|     UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy."); |     UserAccount userAccount1 = new UserAccount("001", "John", "He is a boy."); | ||||||
|  |  | ||||||
|     AppManager.save(userAccount1); |     AppManager.save(userAccount1); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("001"); |     AppManager.find("001"); | ||||||
|     AppManager.find("001"); |     AppManager.find("001"); | ||||||
|   } |   } | ||||||
| @@ -97,21 +103,21 @@ public class App { | |||||||
|    * Read-through and write-around |    * Read-through and write-around | ||||||
|    */ |    */ | ||||||
|   public void useReadThroughAndWriteAroundStrategy() { |   public void useReadThroughAndWriteAroundStrategy() { | ||||||
|     System.out.println("# CachingPolicy.AROUND"); |     LOGGER.info("# CachingPolicy.AROUND"); | ||||||
|     AppManager.initCachingPolicy(CachingPolicy.AROUND); |     AppManager.initCachingPolicy(CachingPolicy.AROUND); | ||||||
|  |  | ||||||
|     UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl."); |     UserAccount userAccount2 = new UserAccount("002", "Jane", "She is a girl."); | ||||||
|  |  | ||||||
|     AppManager.save(userAccount2); |     AppManager.save(userAccount2); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("002"); |     AppManager.find("002"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     userAccount2 = AppManager.find("002"); |     userAccount2 = AppManager.find("002"); | ||||||
|     userAccount2.setUserName("Jane G."); |     userAccount2.setUserName("Jane G."); | ||||||
|     AppManager.save(userAccount2); |     AppManager.save(userAccount2); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("002"); |     AppManager.find("002"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("002"); |     AppManager.find("002"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -119,7 +125,7 @@ public class App { | |||||||
|    * Read-through and write-behind |    * Read-through and write-behind | ||||||
|    */ |    */ | ||||||
|   public void useReadThroughAndWriteBehindStrategy() { |   public void useReadThroughAndWriteBehindStrategy() { | ||||||
|     System.out.println("# CachingPolicy.BEHIND"); |     LOGGER.info("# CachingPolicy.BEHIND"); | ||||||
|     AppManager.initCachingPolicy(CachingPolicy.BEHIND); |     AppManager.initCachingPolicy(CachingPolicy.BEHIND); | ||||||
|  |  | ||||||
|     UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food."); |     UserAccount userAccount3 = new UserAccount("003", "Adam", "He likes food."); | ||||||
| @@ -129,23 +135,23 @@ public class App { | |||||||
|     AppManager.save(userAccount3); |     AppManager.save(userAccount3); | ||||||
|     AppManager.save(userAccount4); |     AppManager.save(userAccount4); | ||||||
|     AppManager.save(userAccount5); |     AppManager.save(userAccount5); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("003"); |     AppManager.find("003"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child."); |     UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child."); | ||||||
|     AppManager.save(userAccount6); |     AppManager.save(userAccount6); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("004"); |     AppManager.find("004"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Cache-Aside |    * Cache-Aside | ||||||
|    */ |    */ | ||||||
|   public void useCacheAsideStategy() { |   public void useCacheAsideStategy() { | ||||||
|     System.out.println("# CachingPolicy.ASIDE"); |     LOGGER.info("# CachingPolicy.ASIDE"); | ||||||
|     AppManager.initCachingPolicy(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 userAccount3 = new UserAccount("003", "Adam", "He likes food."); | ||||||
|     UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats."); |     UserAccount userAccount4 = new UserAccount("004", "Rita", "She hates cats."); | ||||||
| @@ -154,10 +160,10 @@ public class App { | |||||||
|     AppManager.save(userAccount4); |     AppManager.save(userAccount4); | ||||||
|     AppManager.save(userAccount5); |     AppManager.save(userAccount5); | ||||||
|  |  | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("003"); |     AppManager.find("003"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|     AppManager.find("004"); |     AppManager.find("004"); | ||||||
|     System.out.println(AppManager.printCacheContent()); |     LOGGER.info(AppManager.printCacheContent()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.caching; | package com.iluwatar.caching; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -31,6 +34,8 @@ import java.util.List; | |||||||
|  */ |  */ | ||||||
| public class CacheStore { | public class CacheStore { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(CacheStore.class); | ||||||
|  |  | ||||||
|   static LruCache cache; |   static LruCache cache; | ||||||
|  |  | ||||||
|   private CacheStore() { |   private CacheStore() { | ||||||
| @@ -52,10 +57,10 @@ public class CacheStore { | |||||||
|    */ |    */ | ||||||
|   public static UserAccount readThrough(String userId) { |   public static UserAccount readThrough(String userId) { | ||||||
|     if (cache.contains(userId)) { |     if (cache.contains(userId)) { | ||||||
|       System.out.println("# Cache Hit!"); |       LOGGER.info("# Cache Hit!"); | ||||||
|       return cache.get(userId); |       return cache.get(userId); | ||||||
|     } |     } | ||||||
|     System.out.println("# Cache Miss!"); |     LOGGER.info("# Cache Miss!"); | ||||||
|     UserAccount userAccount = DbManager.readFromDb(userId); |     UserAccount userAccount = DbManager.readFromDb(userId); | ||||||
|     cache.set(userId, userAccount); |     cache.set(userId, userAccount); | ||||||
|     return userAccount; |     return userAccount; | ||||||
| @@ -91,13 +96,13 @@ public class CacheStore { | |||||||
|    */ |    */ | ||||||
|   public static UserAccount readThroughWithWriteBackPolicy(String userId) { |   public static UserAccount readThroughWithWriteBackPolicy(String userId) { | ||||||
|     if (cache.contains(userId)) { |     if (cache.contains(userId)) { | ||||||
|       System.out.println("# Cache Hit!"); |       LOGGER.info("# Cache Hit!"); | ||||||
|       return cache.get(userId); |       return cache.get(userId); | ||||||
|     } |     } | ||||||
|     System.out.println("# Cache Miss!"); |     LOGGER.info("# Cache Miss!"); | ||||||
|     UserAccount userAccount = DbManager.readFromDb(userId); |     UserAccount userAccount = DbManager.readFromDb(userId); | ||||||
|     if (cache.isFull()) { |     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(); |       UserAccount toBeWrittenToDb = cache.getLruData(); | ||||||
|       DbManager.upsertDb(toBeWrittenToDb); |       DbManager.upsertDb(toBeWrittenToDb); | ||||||
|     } |     } | ||||||
| @@ -110,7 +115,7 @@ public class CacheStore { | |||||||
|    */ |    */ | ||||||
|   public static void writeBehind(UserAccount userAccount) { |   public static void writeBehind(UserAccount userAccount) { | ||||||
|     if (cache.isFull() && !cache.contains(userAccount.getUserId())) { |     if (cache.isFull() && !cache.contains(userAccount.getUserId())) { | ||||||
|       System.out.println("# Cache is FULL! Writing LRU data to DB..."); |       LOGGER.info("# Cache is FULL! Writing LRU data to DB..."); | ||||||
|       UserAccount toBeWrittenToDb = cache.getLruData(); |       UserAccount toBeWrittenToDb = cache.getLruData(); | ||||||
|       DbManager.upsertDb(toBeWrittenToDb); |       DbManager.upsertDb(toBeWrittenToDb); | ||||||
|     } |     } | ||||||
| @@ -130,7 +135,7 @@ public class CacheStore { | |||||||
|    * Writes remaining content in the cache into the DB. |    * Writes remaining content in the cache into the DB. | ||||||
|    */ |    */ | ||||||
|   public static void flushCache() { |   public static void flushCache() { | ||||||
|     System.out.println("# flushCache..."); |     LOGGER.info("# flushCache..."); | ||||||
|     if (null == cache) { |     if (null == cache) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.caching; | package com.iluwatar.caching; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -38,6 +41,8 @@ import java.util.Map; | |||||||
|  */ |  */ | ||||||
| public class LruCache { | public class LruCache { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(LruCache.class); | ||||||
|  |  | ||||||
|   class Node { |   class Node { | ||||||
|     String userId; |     String userId; | ||||||
|     UserAccount userAccount; |     UserAccount userAccount; | ||||||
| @@ -115,7 +120,7 @@ public class LruCache { | |||||||
|     } else { |     } else { | ||||||
|       Node newNode = new Node(userId, userAccount); |       Node newNode = new Node(userId, userAccount); | ||||||
|       if (cache.size() >= capacity) { |       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. |         cache.remove(end.userId); // remove LRU data from cache. | ||||||
|         remove(end); |         remove(end); | ||||||
|         setHead(newNode); |         setHead(newNode); | ||||||
| @@ -136,7 +141,7 @@ public class LruCache { | |||||||
|   public void invalidate(String userId) { |   public void invalidate(String userId) { | ||||||
|     Node toBeRemoved = cache.remove(userId); |     Node toBeRemoved = cache.remove(userId); | ||||||
|     if (toBeRemoved != null) { |     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); |       remove(toBeRemoved); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.callback; | 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 |  * Callback pattern is more native for functional languages where functions are treated as | ||||||
| @@ -31,6 +34,8 @@ package com.iluwatar.callback; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
| @@ -39,7 +44,7 @@ public class App { | |||||||
|     Callback callback = new Callback() { |     Callback callback = new Callback() { | ||||||
|       @Override |       @Override | ||||||
|       public void call() { |       public void call() { | ||||||
|         System.out.println("I'm done now."); |         LOGGER.info("I'm done now."); | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|     task.executeWith(callback); |     task.executeWith(callback); | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.callback; | 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 |  * 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 { | public class LambdasApp { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(LambdasApp.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
|   public static void main(String[] args) { |   public static void main(String[] args) { | ||||||
|     Task task = new SimpleTask(); |     Task task = new SimpleTask(); | ||||||
|     Callback c = () -> System.out.println("I'm done now."); |     Callback c = () -> LOGGER.info("I'm done now."); | ||||||
|     task.executeWith(c); |     task.executeWith(c); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.callback; | package com.iluwatar.callback; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Implementation of task that need to be executed |  * Implementation of task that need to be executed | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.callback; | |||||||
|  */ |  */ | ||||||
| public class SimpleTask extends Task { | public class SimpleTask extends Task { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTask.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void execute() { |   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; | package com.iluwatar.chain; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * RequestHandler |  * RequestHandler | ||||||
| @@ -29,6 +32,8 @@ package com.iluwatar.chain; | |||||||
|  */ |  */ | ||||||
| public abstract class RequestHandler { | public abstract class RequestHandler { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class); | ||||||
|  |  | ||||||
|   private RequestHandler next; |   private RequestHandler next; | ||||||
|  |  | ||||||
|   public RequestHandler(RequestHandler next) { |   public RequestHandler(RequestHandler next) { | ||||||
| @@ -45,7 +50,7 @@ public abstract class RequestHandler { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   protected void printHandling(Request req) { |   protected void printHandling(Request req) { | ||||||
|     System.out.println(this + " handling request \"" + req + "\""); |     LOGGER.info("{} handling request \"{}\"", this, req); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.command; | package com.iluwatar.command; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Base class for spell targets. |  * Base class for spell targets. | ||||||
| @@ -29,6 +32,8 @@ package com.iluwatar.command; | |||||||
|  */ |  */ | ||||||
| public abstract class Target { | public abstract class Target { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Target.class); | ||||||
|  |  | ||||||
|   private Size size; |   private Size size; | ||||||
|  |  | ||||||
|   private Visibility visibility; |   private Visibility visibility; | ||||||
| @@ -56,8 +61,6 @@ public abstract class Target { | |||||||
|    * Print status |    * Print status | ||||||
|    */ |    */ | ||||||
|   public void printStatus() { |   public void printStatus() { | ||||||
|     System.out.println(String.format("%s, [size=%s] [visibility=%s]", this, getSize(), |     LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility()); | ||||||
|         getVisibility())); |  | ||||||
|     System.out.println(); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.command; | package com.iluwatar.command; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Deque; | import java.util.Deque; | ||||||
| import java.util.LinkedList; | import java.util.LinkedList; | ||||||
|  |  | ||||||
| @@ -32,6 +35,8 @@ import java.util.LinkedList; | |||||||
|  */ |  */ | ||||||
| public class Wizard { | public class Wizard { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); | ||||||
|  |  | ||||||
|   private Deque<Command> undoStack = new LinkedList<>(); |   private Deque<Command> undoStack = new LinkedList<>(); | ||||||
|   private Deque<Command> redoStack = new LinkedList<>(); |   private Deque<Command> redoStack = new LinkedList<>(); | ||||||
|  |  | ||||||
| @@ -41,7 +46,7 @@ public class Wizard { | |||||||
|    * Cast spell |    * Cast spell | ||||||
|    */ |    */ | ||||||
|   public void castSpell(Command command, Target target) { |   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); |     command.execute(target); | ||||||
|     undoStack.offerLast(command); |     undoStack.offerLast(command); | ||||||
|   } |   } | ||||||
| @@ -53,7 +58,7 @@ public class Wizard { | |||||||
|     if (!undoStack.isEmpty()) { |     if (!undoStack.isEmpty()) { | ||||||
|       Command previousSpell = undoStack.pollLast(); |       Command previousSpell = undoStack.pollLast(); | ||||||
|       redoStack.offerLast(previousSpell); |       redoStack.offerLast(previousSpell); | ||||||
|       System.out.println(this + " undoes " + previousSpell); |       LOGGER.info("{} undoes {}", this, previousSpell); | ||||||
|       previousSpell.undo(); |       previousSpell.undo(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -65,7 +70,7 @@ public class Wizard { | |||||||
|     if (!redoStack.isEmpty()) { |     if (!redoStack.isEmpty()) { | ||||||
|       Command previousSpell = redoStack.pollLast(); |       Command previousSpell = redoStack.pollLast(); | ||||||
|       undoStack.offerLast(previousSpell); |       undoStack.offerLast(previousSpell); | ||||||
|       System.out.println(this + " redoes " + previousSpell); |       LOGGER.info("{} redoes {}", this, previousSpell); | ||||||
|       previousSpell.redo(); |       previousSpell.redo(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.composite; | 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 |  * 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 |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
|    * @param args command line args |    * @param args command line args | ||||||
|    */ |    */ | ||||||
|   public static void main(String[] 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(); |     LetterComposite orcMessage = new Messenger().messageFromOrcs(); | ||||||
|     orcMessage.print(); |     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(); |     LetterComposite elfMessage = new Messenger().messageFromElves(); | ||||||
|     elfMessage.print(); |     elfMessage.print(); | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ | |||||||
| package com.iluwatar.composite; | package com.iluwatar.composite; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * Letter |  * Letter | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ package com.iluwatar.composite; | |||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * Sentence |  * Sentence | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ package com.iluwatar.composite; | |||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * Word |  * Word | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.decorator; | 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 |  * The Decorator pattern is a more flexible alternative to subclassing. The Decorator class | ||||||
| @@ -36,6 +39,8 @@ package com.iluwatar.decorator; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -44,17 +49,17 @@ public class App { | |||||||
|   public static void main(String[] args) { |   public static void main(String[] args) { | ||||||
|  |  | ||||||
|     // simple troll |     // simple troll | ||||||
|     System.out.println("A simple looking troll approaches."); |     LOGGER.info("A simple looking troll approaches."); | ||||||
|     Hostile troll = new Troll(); |     Hostile troll = new Troll(); | ||||||
|     troll.attack(); |     troll.attack(); | ||||||
|     troll.fleeBattle(); |     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 |     // 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); |     Hostile smart = new SmartHostile(troll); | ||||||
|     smart.attack(); |     smart.attack(); | ||||||
|     smart.fleeBattle(); |     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; | 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 |  * 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} |  * 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 { | public class SmartHostile implements Hostile { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(SmartHostile.class); | ||||||
|  |  | ||||||
|   private Hostile decorated; |   private Hostile decorated; | ||||||
|  |  | ||||||
|   public SmartHostile(Hostile decorated) { |   public SmartHostile(Hostile decorated) { | ||||||
| @@ -38,7 +43,7 @@ public class SmartHostile implements Hostile { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void attack() { |   public void attack() { | ||||||
|     System.out.println("It throws a rock at you!"); |     LOGGER.info("It throws a rock at you!"); | ||||||
|     decorated.attack(); |     decorated.attack(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -50,7 +55,7 @@ public class SmartHostile implements Hostile { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void fleeBattle() { |   public void fleeBattle() { | ||||||
|     System.out.println("It calls for help!"); |     LOGGER.info("It calls for help!"); | ||||||
|     decorated.fleeBattle(); |     decorated.fleeBattle(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.decorator; | package com.iluwatar.decorator; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Troll implements {@link Hostile} interface directly. |  * Troll implements {@link Hostile} interface directly. | ||||||
| @@ -29,9 +32,11 @@ package com.iluwatar.decorator; | |||||||
|  */ |  */ | ||||||
| public class Troll implements Hostile { | public class Troll implements Hostile { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Troll.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void attack() { |   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 |   @Override | ||||||
| @@ -41,6 +46,6 @@ public class Troll implements Hostile { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void fleeBattle() { |   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; | 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.After; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | 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.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 |  * Date: 12/7/15 - 7:26 PM | ||||||
| @@ -40,31 +42,16 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; | |||||||
|  */ |  */ | ||||||
| public class TrollTest { | public class TrollTest { | ||||||
|  |  | ||||||
|   /** |   private InMemoryAppender appender; | ||||||
|    * 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); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * 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 |   @Before | ||||||
|   public void setUp() { |   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 |   @After | ||||||
|   public void tearDown() { |   public void tearDown() { | ||||||
|     System.setOut(this.stdOutOrig); |     appender.stop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
| @@ -73,12 +60,34 @@ public class TrollTest { | |||||||
|     assertEquals(10, troll.getAttackPower()); |     assertEquals(10, troll.getAttackPower()); | ||||||
|  |  | ||||||
|     troll.attack(); |     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(); |     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; | package com.iluwatar.delegation.simple.printers; | ||||||
|  |  | ||||||
| import com.iluwatar.delegation.simple.Printer; | import com.iluwatar.delegation.simple.Printer; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a Canon Printer, in |  * 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 { | public class CanonPrinter implements Printer { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(CanonPrinter.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * {@inheritDoc} |    * {@inheritDoc} | ||||||
|    */ |    */ | ||||||
|   @Override |   @Override | ||||||
|   public void print(String message) { |   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; | package com.iluwatar.delegation.simple.printers; | ||||||
|  |  | ||||||
| import com.iluwatar.delegation.simple.Printer; | import com.iluwatar.delegation.simple.Printer; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a Epson Printer, in |  * 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 { | public class EpsonPrinter implements Printer { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(EpsonPrinter.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * {@inheritDoc} |    * {@inheritDoc} | ||||||
|    */ |    */ | ||||||
|   @Override |   @Override | ||||||
|   public void print(String message) { |   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; | package com.iluwatar.delegation.simple.printers; | ||||||
|  |  | ||||||
| import com.iluwatar.delegation.simple.Printer; | import com.iluwatar.delegation.simple.Printer; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a HP Printer, in |  * 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 { | public class HpPrinter implements Printer { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(HpPrinter.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * {@inheritDoc} |    * {@inheritDoc} | ||||||
|    */ |    */ | ||||||
|   @Override |   @Override | ||||||
|   public void print(String message) { |   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; | 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.CanonPrinter; | ||||||
| import com.iluwatar.delegation.simple.printers.EpsonPrinter; | import com.iluwatar.delegation.simple.printers.EpsonPrinter; | ||||||
| import com.iluwatar.delegation.simple.printers.HpPrinter; | 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.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; | import static org.junit.Assert.assertEquals; | ||||||
|  |  | ||||||
| public class DelegateTest { | public class DelegateTest { | ||||||
|  |  | ||||||
|   private static final String MESSAGE = "Test Message Printed"; |   private InMemoryAppender appender; | ||||||
|  |  | ||||||
|   @Rule |   @Before | ||||||
|   public final SystemOutRule systemOutRule = new SystemOutRule().enableLog(); |   public void setUp() { | ||||||
|  |     appender = new InMemoryAppender(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @After | ||||||
|  |   public void tearDown() { | ||||||
|  |     appender.stop(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private static final String MESSAGE = "Test Message Printed"; | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   public void testCanonPrinter() throws Exception { |   public void testCanonPrinter() throws Exception { | ||||||
|     PrinterController printerController = new PrinterController(new CanonPrinter()); |     PrinterController printerController = new PrinterController(new CanonPrinter()); | ||||||
|     printerController.print(MESSAGE); |     printerController.print(MESSAGE); | ||||||
|  |  | ||||||
|     assertEquals("Canon Printer : Test Message Printed", systemOutRule.getLog()); |     assertEquals("Canon Printer : Test Message Printed", appender.getLastMessage()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
| @@ -51,7 +67,7 @@ public class DelegateTest { | |||||||
|     PrinterController printerController = new PrinterController(new HpPrinter()); |     PrinterController printerController = new PrinterController(new HpPrinter()); | ||||||
|     printerController.print(MESSAGE); |     printerController.print(MESSAGE); | ||||||
|  |  | ||||||
|     assertEquals("HP Printer : Test Message Printed", systemOutRule.getLog()); |     assertEquals("HP Printer : Test Message Printed", appender.getLastMessage()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
| @@ -59,7 +75,30 @@ public class DelegateTest { | |||||||
|     PrinterController printerController = new PrinterController(new EpsonPrinter()); |     PrinterController printerController = new PrinterController(new EpsonPrinter()); | ||||||
|     printerController.print(MESSAGE); |     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; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Tobacco abstraction |  * Tobacco abstraction | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.dependency.injection; | |||||||
|  */ |  */ | ||||||
| public abstract class Tobacco { | public abstract class Tobacco { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Tobacco.class); | ||||||
|  |  | ||||||
|   public void smoke(Wizard wizard) { |   public void smoke(Wizard wizard) { | ||||||
|     System.out.println(String.format("%s smoking %s", wizard.getClass().getSimpleName(), this |     LOGGER.info("{} smoking {}", wizard.getClass().getSimpleName(), | ||||||
|         .getClass().getSimpleName())); |         this.getClass().getSimpleName()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,18 +22,31 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.dependency.injection; | 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 org.junit.Test; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.times; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.verify; |  | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/10/15 - 8:40 PM |  * Date: 12/10/15 - 8:40 PM | ||||||
|  * |  * | ||||||
|  * @author Jeroen Meulemeester |  * @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 |    * Test if the {@link AdvancedWizard} smokes whatever instance of {@link Tobacco} is passed to him | ||||||
| @@ -51,12 +64,13 @@ public class AdvancedWizardTest extends StdOutTest { | |||||||
|       advancedWizard.smoke(); |       advancedWizard.smoke(); | ||||||
|  |  | ||||||
|       // Verify if the wizard is smoking the correct tobacco ... |       // Verify if the wizard is smoking the correct tobacco ... | ||||||
|       verify(getStdOutMock(), times(1)).println("AdvancedWizard smoking " + tobacco.getClass().getSimpleName()); |       assertEquals("AdvancedWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage()); | ||||||
|  |  | ||||||
|       // ... and nothing else is happening. |  | ||||||
|       verifyNoMoreInteractions(getStdOutMock()); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // ... and nothing else is happening. | ||||||
|  |     assertEquals(tobaccos.length, appender.getLogSize()); | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,19 +25,31 @@ package com.iluwatar.dependency.injection; | |||||||
| import com.google.inject.AbstractModule; | import com.google.inject.AbstractModule; | ||||||
| import com.google.inject.Guice; | import com.google.inject.Guice; | ||||||
| import com.google.inject.Injector; | 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 org.junit.Test; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.times; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.verify; |  | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/10/15 - 8:57 PM |  * Date: 12/10/15 - 8:57 PM | ||||||
|  * |  * | ||||||
|  * @author Jeroen Meulemeester |  * @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 |    * 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(); |       guiceWizard.smoke(); | ||||||
|  |  | ||||||
|       // Verify if the wizard is smoking the correct tobacco ... |       // Verify if the wizard is smoking the correct tobacco ... | ||||||
|       verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobacco.getClass().getSimpleName()); |       assertEquals("GuiceWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage()); | ||||||
|  |  | ||||||
|       // ... and nothing else is happening. |  | ||||||
|       verifyNoMoreInteractions(getStdOutMock()); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // ... and nothing else is happening. | ||||||
|  |     assertEquals(tobaccos.length, appender.getLogSize()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -89,12 +100,11 @@ public class GuiceWizardTest extends StdOutTest { | |||||||
|       guiceWizard.smoke(); |       guiceWizard.smoke(); | ||||||
|  |  | ||||||
|       // Verify if the wizard is smoking the correct tobacco ... |       // Verify if the wizard is smoking the correct tobacco ... | ||||||
|       verify(getStdOutMock(), times(1)).println("GuiceWizard smoking " + tobaccoClass.getSimpleName()); |       assertEquals("GuiceWizard smoking " + tobaccoClass.getSimpleName(), appender.getLastMessage()); | ||||||
|  |  | ||||||
|       // ... and nothing else is happening. |  | ||||||
|       verifyNoMoreInteractions(getStdOutMock()); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // ... and nothing else is happening. | ||||||
|  |     assertEquals(tobaccos.length, appender.getLogSize()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,16 +22,31 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.dependency.injection; | 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 org.junit.Test; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.*; | import static org.junit.Assert.assertEquals; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/10/15 - 8:26 PM |  * Date: 12/10/15 - 8:26 PM | ||||||
|  * |  * | ||||||
|  * @author Jeroen Meulemeester |  * @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 |    * 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() { |   public void testSmoke() { | ||||||
|     final SimpleWizard simpleWizard = new SimpleWizard(); |     final SimpleWizard simpleWizard = new SimpleWizard(); | ||||||
|     simpleWizard.smoke(); |     simpleWizard.smoke(); | ||||||
|     verify(getStdOutMock(), times(1)).println("SimpleWizard smoking OldTobyTobacco"); |     assertEquals("SimpleWizard smoking OldTobyTobacco", appender.getLastMessage()); | ||||||
|     verifyNoMoreInteractions(getStdOutMock()); |     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; | package com.iluwatar.doublechecked.locking; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
| @@ -40,6 +43,8 @@ import java.util.concurrent.TimeUnit; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -58,7 +63,7 @@ public class App { | |||||||
|     try { |     try { | ||||||
|       executorService.awaitTermination(5, TimeUnit.SECONDS); |       executorService.awaitTermination(5, TimeUnit.SECONDS); | ||||||
|     } catch (InterruptedException e) { |     } 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; | package com.iluwatar.doublechecked.locking; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -35,6 +38,8 @@ import java.util.concurrent.locks.ReentrantLock; | |||||||
|  */ |  */ | ||||||
| public class Inventory { | public class Inventory { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Inventory.class); | ||||||
|  |  | ||||||
|   private final int inventorySize; |   private final int inventorySize; | ||||||
|   private final List<Item> items; |   private final List<Item> items; | ||||||
|   private final Lock lock; |   private final Lock lock; | ||||||
| @@ -57,8 +62,7 @@ public class Inventory { | |||||||
|       try { |       try { | ||||||
|         if (items.size() < inventorySize) { |         if (items.size() < inventorySize) { | ||||||
|           items.add(item); |           items.add(item); | ||||||
|           System.out.println(Thread.currentThread() + ": items.size()=" + items.size() |           LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items.size(), inventorySize); | ||||||
|               + ", inventorySize=" + inventorySize); |  | ||||||
|           return true; |           return true; | ||||||
|         } |         } | ||||||
|       } finally { |       } 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; | 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.After; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | 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.List; | ||||||
| import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
| import static junit.framework.Assert.assertTrue; |  | ||||||
| import static junit.framework.TestCase.assertEquals; | import static junit.framework.TestCase.assertEquals; | ||||||
| import static org.junit.Assert.assertNotNull; | import static org.junit.Assert.assertNotNull; | ||||||
| import static org.mockito.Mockito.mock; | import static org.junit.Assert.assertTrue; | ||||||
| import static org.mockito.Mockito.times; |  | ||||||
| import static org.mockito.Mockito.verify; |  | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/10/15 - 9:34 PM |  * Date: 12/10/15 - 9:34 PM | ||||||
| @@ -48,31 +47,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; | |||||||
|  */ |  */ | ||||||
| public class InventoryTest { | public class InventoryTest { | ||||||
|  |  | ||||||
|   /** |   private InMemoryAppender appender; | ||||||
|    * 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); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * 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 |   @Before | ||||||
|   public void setUp() { |   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 |   @After | ||||||
|   public void tearDown() { |   public void tearDown() { | ||||||
|     System.setOut(this.stdOutOrig); |     appender.stop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -112,21 +96,32 @@ public class InventoryTest { | |||||||
|     assertNotNull(items); |     assertNotNull(items); | ||||||
|     assertEquals(INVENTORY_SIZE, items.size()); |     assertEquals(INVENTORY_SIZE, items.size()); | ||||||
|  |  | ||||||
|     // Capture all stdOut messages ... |     assertEquals(INVENTORY_SIZE, appender.getLogSize()); | ||||||
|     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()); |  | ||||||
|  |  | ||||||
|     // ... and check if the inventory size is increasing continuously |     // ... and check if the inventory size is increasing continuously | ||||||
|     for (int i = 0; i < values.size(); i++) { |     for (int i = 0; i < items.size(); i++) { | ||||||
|       assertNotNull(values.get(i)); |       assertTrue(appender.log.get(i).getFormattedMessage().contains("items.size()=" + (i + 1))); | ||||||
|       assertTrue(values.get(i).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; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| @@ -45,6 +48,8 @@ import java.util.List; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -58,8 +63,8 @@ public class App { | |||||||
|     objects.add(new SpaceStationMir(1, 1, 2, 2)); |     objects.add(new SpaceStationMir(1, 1, 2, 2)); | ||||||
|     objects.add(new Meteoroid(10, 10, 15, 15)); |     objects.add(new Meteoroid(10, 10, 15, 15)); | ||||||
|     objects.add(new SpaceStationIss(12, 12, 14, 14)); |     objects.add(new SpaceStationIss(12, 12, 14, 14)); | ||||||
|     objects.stream().forEach(o -> System.out.println(o)); |     objects.stream().forEach(o -> LOGGER.info(o.toString())); | ||||||
|     System.out.println(""); |     LOGGER.info(""); | ||||||
|  |  | ||||||
|     // collision check |     // collision check | ||||||
|     objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { |     objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { | ||||||
| @@ -67,10 +72,10 @@ public class App { | |||||||
|         o1.collision(o2); |         o1.collision(o2); | ||||||
|       } |       } | ||||||
|     })); |     })); | ||||||
|     System.out.println(""); |     LOGGER.info(""); | ||||||
|  |  | ||||||
|     // output eventual object statuses |     // output eventual object statuses | ||||||
|     objects.stream().forEach(o -> System.out.println(o)); |     objects.stream().forEach(o -> LOGGER.info(o.toString())); | ||||||
|     System.out.println(""); |     LOGGER.info(""); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Meteoroid game object |  * Meteoroid game object | ||||||
| @@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch; | |||||||
|  */ |  */ | ||||||
| public class Meteoroid extends GameObject { | public class Meteoroid extends GameObject { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Meteoroid.class); | ||||||
|  |  | ||||||
|   public Meteoroid(int left, int top, int right, int bottom) { |   public Meteoroid(int left, int top, int right, int bottom) { | ||||||
|     super(left, top, right, bottom); |     super(left, top, right, bottom); | ||||||
|   } |   } | ||||||
| @@ -40,25 +45,21 @@ public class Meteoroid extends GameObject { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(FlamingAsteroid asteroid) { |   public void collisionResolve(FlamingAsteroid asteroid) { | ||||||
|     System.out.println(String.format("%s hits %s.", asteroid.getClass().getSimpleName(), this |     LOGGER.info("{} hits {}.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|         .getClass().getSimpleName())); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(Meteoroid meteoroid) { |   public void collisionResolve(Meteoroid meteoroid) { | ||||||
|     System.out.println(String.format("%s hits %s.", meteoroid.getClass().getSimpleName(), this |     LOGGER.info("{} hits {}.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|         .getClass().getSimpleName())); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(SpaceStationMir mir) { |   public void collisionResolve(SpaceStationMir mir) { | ||||||
|     System.out.println(String.format("%s hits %s.", mir.getClass().getSimpleName(), this.getClass() |     LOGGER.info("{} hits {}.", mir.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|         .getSimpleName())); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(SpaceStationIss iss) { |   public void collisionResolve(SpaceStationIss iss) { | ||||||
|     System.out.println(String.format("%s hits %s.", iss.getClass().getSimpleName(), this.getClass() |     LOGGER.info("{} hits {}.", iss.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|         .getSimpleName())); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Space station Mir game object |  * Space station Mir game object | ||||||
| @@ -29,6 +32,8 @@ package com.iluwatar.doubledispatch; | |||||||
|  */ |  */ | ||||||
| public class SpaceStationMir extends GameObject { | public class SpaceStationMir extends GameObject { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(SpaceStationMir.class); | ||||||
|  |  | ||||||
|   public SpaceStationMir(int left, int top, int right, int bottom) { |   public SpaceStationMir(int left, int top, int right, int bottom) { | ||||||
|     super(left, top, right, bottom); |     super(left, top, right, bottom); | ||||||
|   } |   } | ||||||
| @@ -40,31 +45,30 @@ public class SpaceStationMir extends GameObject { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(FlamingAsteroid asteroid) { |   public void collisionResolve(FlamingAsteroid asteroid) { | ||||||
|     System.out.println(String.format("%s hits %s. %s is damaged! %s is set on fire!", asteroid |     LOGGER.info("{} hits {}. {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(), | ||||||
|         .getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass() |         this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|         .getSimpleName(), this.getClass().getSimpleName())); |  | ||||||
|     setDamaged(true); |     setDamaged(true); | ||||||
|     setOnFire(true); |     setOnFire(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(Meteoroid meteoroid) { |   public void collisionResolve(Meteoroid meteoroid) { | ||||||
|     System.out.println(String.format("%s hits %s. %s is damaged!", meteoroid.getClass() |     LOGGER.info("{} hits {}. {} is damaged!", meteoroid.getClass().getSimpleName(), | ||||||
|         .getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName())); |         this.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|     setDamaged(true); |     setDamaged(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(SpaceStationMir mir) { |   public void collisionResolve(SpaceStationMir mir) { | ||||||
|     System.out.println(String.format("%s hits %s. %s is damaged!", mir.getClass().getSimpleName(), |     LOGGER.info("{} hits {}. {} is damaged!", mir.getClass().getSimpleName(), | ||||||
|         this.getClass().getSimpleName(), this.getClass().getSimpleName())); |         this.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|     setDamaged(true); |     setDamaged(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(SpaceStationIss iss) { |   public void collisionResolve(SpaceStationIss iss) { | ||||||
|     System.out.println(String.format("%s hits %s. %s is damaged!", iss.getClass().getSimpleName(), |     LOGGER.info("{} hits {}. {} is damaged!", iss.getClass().getSimpleName(), | ||||||
|         this.getClass().getSimpleName(), this.getClass().getSimpleName())); |         this.getClass().getSimpleName(), this.getClass().getSimpleName()); | ||||||
|     setDamaged(true); |     setDamaged(true); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,17 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
| import org.junit.After; |  | ||||||
| import org.junit.Before; |  | ||||||
|  |  | ||||||
| import java.io.PrintStream; |  | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
|  |  | ||||||
| import static org.junit.Assert.assertEquals; | 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 |  * Date: 12/10/15 - 8:37 PM | ||||||
| @@ -41,43 +33,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; | |||||||
|  */ |  */ | ||||||
| public abstract class CollisionTest<O extends GameObject> { | 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 |    * Get the tested object | ||||||
|    * |    * | ||||||
| @@ -106,9 +61,6 @@ public abstract class CollisionTest<O extends GameObject> { | |||||||
|  |  | ||||||
|     tested.collision(other); |     tested.collision(other); | ||||||
|  |  | ||||||
|     verify(getStdOutMock(), times(1)).println(description); |  | ||||||
|     verifyNoMoreInteractions(getStdOutMock()); |  | ||||||
|  |  | ||||||
|     testOnFire(other, tested, otherOnFire); |     testOnFire(other, tested, otherOnFire); | ||||||
|     testDamaged(other, tested, otherDamaged); |     testDamaged(other, tested, otherDamaged); | ||||||
|  |  | ||||||
| @@ -129,8 +81,8 @@ public abstract class CollisionTest<O extends GameObject> { | |||||||
|     final String targetName = target.getClass().getSimpleName(); |     final String targetName = target.getClass().getSimpleName(); | ||||||
|     final String otherName = other.getClass().getSimpleName(); |     final String otherName = other.getClass().getSimpleName(); | ||||||
|  |  | ||||||
|     final String errorMessage = expectTargetOnFire  |     final String errorMessage = expectTargetOnFire | ||||||
|         ? "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!"  |         ? "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!" | ||||||
|         : "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!"; |         : "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!"; | ||||||
|  |  | ||||||
|     assertEquals(errorMessage, expectTargetOnFire, target.isOnFire()); |     assertEquals(errorMessage, expectTargetOnFire, target.isOnFire()); | ||||||
| @@ -149,7 +101,7 @@ public abstract class CollisionTest<O extends GameObject> { | |||||||
|     final String otherName = other.getClass().getSimpleName(); |     final String otherName = other.getClass().getSimpleName(); | ||||||
|  |  | ||||||
|     final String errorMessage = expectedDamage |     final String errorMessage = expectedDamage | ||||||
|         ? "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!"  |         ? "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!" | ||||||
|         : "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!"; |         : "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!"; | ||||||
|  |  | ||||||
|     assertEquals(errorMessage, expectedDamage, target.isDamaged()); |     assertEquals(errorMessage, expectedDamage, target.isDamaged()); | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.event.aggregator; | package com.iluwatar.event.aggregator; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * KingJoffrey observes events from {@link KingsHand}. |  * KingJoffrey observes events from {@link KingsHand}. | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.event.aggregator; | |||||||
|  */ |  */ | ||||||
| public class KingJoffrey implements EventObserver { | public class KingJoffrey implements EventObserver { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(KingJoffrey.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void onEvent(Event e) { |   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; | 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.After; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | 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.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.times; |  | ||||||
| import static org.mockito.Mockito.verify; |  | ||||||
| import static org.mockito.Mockito.verifyZeroInteractions; |  | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/12/15 - 3:04 PM |  * Date: 12/12/15 - 3:04 PM | ||||||
| @@ -41,31 +42,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; | |||||||
|  */ |  */ | ||||||
| public class KingJoffreyTest { | public class KingJoffreyTest { | ||||||
|  |  | ||||||
|   /** |   private InMemoryAppender appender; | ||||||
|    * 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); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * 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 |   @Before | ||||||
|   public void setUp() { |   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 |   @After | ||||||
|   public void tearDown() { |   public void tearDown() { | ||||||
|     System.setOut(this.stdOutOrig); |     appender.stop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -75,15 +61,38 @@ public class KingJoffreyTest { | |||||||
|   public void testOnEvent() { |   public void testOnEvent() { | ||||||
|     final KingJoffrey kingJoffrey = new KingJoffrey(); |     final KingJoffrey kingJoffrey = new KingJoffrey(); | ||||||
|  |  | ||||||
|     for (final Event event : Event.values()) { |     for (int i = 0; i < Event.values().length; ++i) { | ||||||
|       verifyZeroInteractions(this.stdOutMock); |       assertEquals(i, appender.getLogSize()); | ||||||
|  |       Event event = Event.values()[i]; | ||||||
|       kingJoffrey.onEvent(event); |       kingJoffrey.onEvent(event); | ||||||
|  |  | ||||||
|       final String expectedMessage = "Received event from the King's Hand: " + event.toString(); |       final String expectedMessage = "Received event from the King's Hand: " + event.toString(); | ||||||
|       verify(this.stdOutMock, times(1)).println(expectedMessage); |       assertEquals(expectedMessage, appender.getLastMessage()); | ||||||
|       verifyNoMoreInteractions(this.stdOutMock); |       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,38 +16,43 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.event.asynchronous; | package com.iluwatar.event.asynchronous; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.util.Properties; | import java.util.Properties; | ||||||
| import java.util.Scanner; | import java.util.Scanner; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * This application demonstrates the <b>Event-based Asynchronous</b> pattern. Essentially, users (of the pattern) may |  * This application demonstrates the <b>Event-based Asynchronous</b> pattern. Essentially, users (of the pattern) may | ||||||
|  * choose to run events in an Asynchronous or Synchronous mode. There can be multiple Asynchronous events running at |  * choose to run events in an Asynchronous or Synchronous mode. There can be multiple Asynchronous events running at | ||||||
|  * once but only one Synchronous event can run at a time. Asynchronous events are synonymous to multi-threads. The key |  * once but only one Synchronous event can run at a time. Asynchronous events are synonymous to multi-threads. The key | ||||||
|  * point here is that the threads run in the background and the user is free to carry on with other processes. Once an |  * point here is that the threads run in the background and the user is free to carry on with other processes. Once an | ||||||
|  * event is complete, the appropriate listener/callback method will be called. The listener then proceeds to carry out |  * event is complete, the appropriate listener/callback method will be called. The listener then proceeds to carry out | ||||||
|  * further processing depending on the needs of the user. |  * further processing depending on the needs of the user. | ||||||
|  *  |  * | ||||||
|  * The {@link EventManager} manages the events/threads that the user creates. Currently, the supported event operations |  * The {@link EventManager} manages the events/threads that the user creates. Currently, the supported event operations | ||||||
|  * are: <code>start</code>, <code>stop</code>, <code>getStatus</code>. For Synchronous events, the user is unable to |  * are: <code>start</code>, <code>stop</code>, <code>getStatus</code>. For Synchronous events, the user is unable to | ||||||
|  * start another (Synchronous) event if one is already running at the time. The running event would have to either be |  * start another (Synchronous) event if one is already running at the time. The running event would have to either be | ||||||
|  * stopped or completed before a new event can be started. |  * stopped or completed before a new event can be started. | ||||||
|  *  |  * | ||||||
|  * The Event-based Asynchronous Pattern makes available the advantages of multithreaded applications while hiding many |  * The Event-based Asynchronous Pattern makes available the advantages of multithreaded applications while hiding many | ||||||
|  * of the complex issues inherent in multithreaded design. Using a class that supports this pattern can allow you to:- |  * of the complex issues inherent in multithreaded design. Using a class that supports this pattern can allow you to:- | ||||||
|  * (1) Perform time-consuming tasks, such as downloads and database operations, "in the background," without |  * (1) Perform time-consuming tasks, such as downloads and database operations, "in the background," without | ||||||
|  * interrupting your application. (2) Execute multiple operations simultaneously, receiving notifications when each |  * interrupting your application. (2) Execute multiple operations simultaneously, receiving notifications when each | ||||||
|  * completes. (3) Wait for resources to become available without stopping ("hanging") your application. (4) Communicate |  * completes. (3) Wait for resources to become available without stopping ("hanging") your application. (4) Communicate | ||||||
|  * with pending asynchronous operations using the familiar events-and-delegates model. |  * with pending asynchronous operations using the familiar events-and-delegates model. | ||||||
|  *  |  * | ||||||
|  * @see EventManager |  * @see EventManager | ||||||
|  * @see Event |  * @see Event | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   public static final String PROP_FILE_NAME = "config.properties"; |   public static final String PROP_FILE_NAME = "config.properties"; | ||||||
|  |  | ||||||
|   boolean interactiveMode = false; |   boolean interactiveMode = false; | ||||||
| @@ -77,7 +82,7 @@ public class App { | |||||||
|       try { |       try { | ||||||
|         prop.load(inputStream); |         prop.load(inputStream); | ||||||
|       } catch (IOException e) { |       } 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"); |       String property = prop.getProperty("INTERACTIVE_MODE"); | ||||||
|       if (property.equalsIgnoreCase("YES")) { |       if (property.equalsIgnoreCase("YES")) { | ||||||
| @@ -106,27 +111,27 @@ public class App { | |||||||
|     try { |     try { | ||||||
|       // Create an Asynchronous event. |       // Create an Asynchronous event. | ||||||
|       int aEventId = eventManager.createAsync(60); |       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); |       eventManager.start(aEventId); | ||||||
|       System.out.println("Async Event [" + aEventId + "] has been started."); |       LOGGER.info("Async Event [{}] has been started.", aEventId); | ||||||
|  |  | ||||||
|       // Create a Synchronous event. |       // Create a Synchronous event. | ||||||
|       int sEventId = eventManager.create(60); |       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); |       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(aEventId); | ||||||
|       eventManager.status(sEventId); |       eventManager.status(sEventId); | ||||||
|  |  | ||||||
|       eventManager.cancel(aEventId); |       eventManager.cancel(aEventId); | ||||||
|       System.out.println("Async Event [" + aEventId + "] has been stopped."); |       LOGGER.info("Async Event [{}] has been stopped.", aEventId); | ||||||
|       eventManager.cancel(sEventId); |       eventManager.cancel(sEventId); | ||||||
|       System.out.println("Sync Event [" + sEventId + "] has been stopped."); |       LOGGER.info("Sync Event [{}] has been stopped.", sEventId); | ||||||
|  |  | ||||||
|     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException |     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException | ||||||
|         | InvalidOperationException e) { |         | InvalidOperationException e) { | ||||||
|       System.out.println(e.getMessage()); |       LOGGER.error(e.getMessage()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -139,58 +144,58 @@ public class App { | |||||||
|     Scanner s = new Scanner(System.in); |     Scanner s = new Scanner(System.in); | ||||||
|     int option = -1; |     int option = -1; | ||||||
|     while (option != 4) { |     while (option != 4) { | ||||||
|       System.out.println("Hello. Would you like to boil some eggs?"); |       LOGGER.info("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"); |       LOGGER.info("(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("Choose [1,2,3,4]: "); | ||||||
|       option = s.nextInt(); |       option = s.nextInt(); | ||||||
|  |  | ||||||
|       if (option == 1) { |       if (option == 1) { | ||||||
|         s.nextLine(); |         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(); |         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(); |         int eventTime = s.nextInt(); | ||||||
|         if (eventType.equalsIgnoreCase("A")) { |         if (eventType.equalsIgnoreCase("A")) { | ||||||
|           try { |           try { | ||||||
|             int eventId = eventManager.createAsync(eventTime); |             int eventId = eventManager.createAsync(eventTime); | ||||||
|             eventManager.start(eventId); |             eventManager.start(eventId); | ||||||
|             System.out.println("Egg [" + eventId + "] is being boiled."); |             LOGGER.info("Egg [{}] is being boiled.", eventId); | ||||||
|           } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { |           } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { | ||||||
|             System.out.println(e.getMessage()); |             LOGGER.error(e.getMessage()); | ||||||
|           } |           } | ||||||
|         } else if (eventType.equalsIgnoreCase("S")) { |         } else if (eventType.equalsIgnoreCase("S")) { | ||||||
|           try { |           try { | ||||||
|             int eventId = eventManager.create(eventTime); |             int eventId = eventManager.create(eventTime); | ||||||
|             eventManager.start(eventId); |             eventManager.start(eventId); | ||||||
|             System.out.println("Egg [" + eventId + "] is being boiled."); |             LOGGER.info("Egg [{}] is being boiled.", eventId); | ||||||
|           } catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException |           } catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException | ||||||
|               | EventDoesNotExistException e) { |               | EventDoesNotExistException e) { | ||||||
|             System.out.println(e.getMessage()); |             LOGGER.error(e.getMessage()); | ||||||
|           } |           } | ||||||
|         } else { |         } else { | ||||||
|           System.out.println("Unknown event type."); |           LOGGER.info("Unknown event type."); | ||||||
|         } |         } | ||||||
|       } else if (option == 2) { |       } else if (option == 2) { | ||||||
|         System.out.print("Which egg?: "); |         LOGGER.info("Which egg?: "); | ||||||
|         int eventId = s.nextInt(); |         int eventId = s.nextInt(); | ||||||
|         try { |         try { | ||||||
|           eventManager.cancel(eventId); |           eventManager.cancel(eventId); | ||||||
|           System.out.println("Egg [" + eventId + "] is removed from boiler."); |           LOGGER.info("Egg [{}] is removed from boiler.", eventId); | ||||||
|         } catch (EventDoesNotExistException e) { |         } catch (EventDoesNotExistException e) { | ||||||
|           System.out.println(e.getMessage()); |           LOGGER.error(e.getMessage()); | ||||||
|         } |         } | ||||||
|       } else if (option == 3) { |       } else if (option == 3) { | ||||||
|         s.nextLine(); |         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(); |         String eggChoice = s.nextLine(); | ||||||
|  |  | ||||||
|         if (eggChoice.equalsIgnoreCase("O")) { |         if (eggChoice.equalsIgnoreCase("O")) { | ||||||
|           System.out.print("Which egg?: "); |           LOGGER.info("Which egg?: "); | ||||||
|           int eventId = s.nextInt(); |           int eventId = s.nextInt(); | ||||||
|           try { |           try { | ||||||
|             eventManager.status(eventId); |             eventManager.status(eventId); | ||||||
|           } catch (EventDoesNotExistException e) { |           } catch (EventDoesNotExistException e) { | ||||||
|             System.out.println(e.getMessage()); |             LOGGER.error(e.getMessage()); | ||||||
|           } |           } | ||||||
|         } else if (eggChoice.equalsIgnoreCase("A")) { |         } else if (eggChoice.equalsIgnoreCase("A")) { | ||||||
|           eventManager.statusOfAllEvents(); |           eventManager.statusOfAllEvents(); | ||||||
|   | |||||||
| @@ -16,13 +16,18 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.event.asynchronous; | package com.iluwatar.event.asynchronous; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * Each Event runs as a separate/individual thread. |  * Each Event runs as a separate/individual thread. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class Event implements IEvent, Runnable { | public class Event implements IEvent, Runnable { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Event.class); | ||||||
|  |  | ||||||
|   private int eventId; |   private int eventId; | ||||||
|   private int eventTime; |   private int eventTime; | ||||||
|   private boolean isSynchronous; |   private boolean isSynchronous; | ||||||
| @@ -31,7 +36,7 @@ public class Event implements IEvent, Runnable { | |||||||
|   private ThreadCompleteListener eventListener; |   private ThreadCompleteListener eventListener; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    *  |    * | ||||||
|    * @param eventId event ID |    * @param eventId event ID | ||||||
|    * @param eventTime event time |    * @param eventTime event time | ||||||
|    * @param isSynchronous is of synchronous type |    * @param isSynchronous is of synchronous type | ||||||
| @@ -63,9 +68,9 @@ public class Event implements IEvent, Runnable { | |||||||
|   @Override |   @Override | ||||||
|   public void status() { |   public void status() { | ||||||
|     if (!isComplete) { |     if (!isComplete) { | ||||||
|       System.out.println("[" + eventId + "] is not done."); |       LOGGER.info("[{}] is not done.", eventId); | ||||||
|     } else { |     } else { | ||||||
|       System.out.println("[" + eventId + "] is done."); |       LOGGER.info("[{}] is done.", eventId); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ import java.util.Random; | |||||||
| import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * | ||||||
|  * EventManager handles and maintains a pool of event threads. {@link Event} threads are created upon user request. Thre |  * EventManager handles and maintains a pool of event threads. {@link Event} threads are created upon user request. Thre | ||||||
|  * are two types of events; Asynchronous and Synchronous. There can be multiple Asynchronous events running at once but |  * are two types of events; Asynchronous and Synchronous. There can be multiple Asynchronous events running at once but | ||||||
|  * only one Synchronous event running at a time. Currently supported event operations are: start, stop, and getStatus. |  * only one Synchronous event running at a time. Currently supported event operations are: start, stop, and getStatus. | ||||||
| @@ -52,7 +52,7 @@ public class EventManager implements ThreadCompleteListener { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Create a Synchronous event. |    * Create a Synchronous event. | ||||||
|    *  |    * | ||||||
|    * @param eventTime Time an event should run for. |    * @param eventTime Time an event should run for. | ||||||
|    * @return eventId |    * @return eventId | ||||||
|    * @throws MaxNumOfEventsAllowedException When too many events are running at a time. |    * @throws MaxNumOfEventsAllowedException When too many events are running at a time. | ||||||
| @@ -74,7 +74,7 @@ public class EventManager implements ThreadCompleteListener { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Create an Asynchronous event. |    * Create an Asynchronous event. | ||||||
|    *  |    * | ||||||
|    * @param eventTime Time an event should run for. |    * @param eventTime Time an event should run for. | ||||||
|    * @return eventId |    * @return eventId | ||||||
|    * @throws MaxNumOfEventsAllowedException When too many events are running at a time. |    * @throws MaxNumOfEventsAllowedException When too many events are running at a time. | ||||||
| @@ -106,7 +106,7 @@ public class EventManager implements ThreadCompleteListener { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Starts event. |    * Starts event. | ||||||
|    *  |    * | ||||||
|    * @param eventId The event that needs to be started. |    * @param eventId The event that needs to be started. | ||||||
|    * @throws EventDoesNotExistException If event does not exist in our eventPool. |    * @throws EventDoesNotExistException If event does not exist in our eventPool. | ||||||
|    */ |    */ | ||||||
| @@ -120,7 +120,7 @@ public class EventManager implements ThreadCompleteListener { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Stops event. |    * Stops event. | ||||||
|    *  |    * | ||||||
|    * @param eventId The event that needs to be stopped. |    * @param eventId The event that needs to be stopped. | ||||||
|    * @throws EventDoesNotExistException If event does not exist in our eventPool. |    * @throws EventDoesNotExistException If event does not exist in our eventPool. | ||||||
|    */ |    */ | ||||||
| @@ -139,7 +139,7 @@ public class EventManager implements ThreadCompleteListener { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Get status of a running event. |    * Get status of a running event. | ||||||
|    *  |    * | ||||||
|    * @param eventId The event to inquire status of. |    * @param eventId The event to inquire status of. | ||||||
|    * @throws EventDoesNotExistException If event does not exist in our eventPool. |    * @throws EventDoesNotExistException If event does not exist in our eventPool. | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -16,10 +16,12 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.event.asynchronous; | package com.iluwatar.event.asynchronous; | ||||||
|  |  | ||||||
| import static org.junit.Assert.assertTrue; |  | ||||||
|  |  | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | 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 { | public class EventAsynchronousTest { | ||||||
|   App app; |   App app; | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(EventAsynchronousTest.class); | ||||||
|  |  | ||||||
|   @Before |   @Before | ||||||
|   public void setUp() { |   public void setUp() { | ||||||
|     app = new App(); |     app = new App(); | ||||||
| @@ -46,7 +50,7 @@ public class EventAsynchronousTest { | |||||||
|       eventManager.cancel(aEventId); |       eventManager.cancel(aEventId); | ||||||
|       assertTrue(eventManager.getEventPool().size() == 0); |       assertTrue(eventManager.getEventPool().size() == 0); | ||||||
|     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { |     } 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); |       assertTrue(eventManager.getEventPool().size() == 0); | ||||||
|     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException |     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException | ||||||
|         | InvalidOperationException e) { |         | InvalidOperationException e) { | ||||||
|       System.out.println(e.getMessage()); |       LOGGER.error(e.getMessage()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -76,7 +80,7 @@ public class EventAsynchronousTest { | |||||||
|       sEventId = eventManager.create(60); |       sEventId = eventManager.create(60); | ||||||
|       eventManager.start(sEventId); |       eventManager.start(sEventId); | ||||||
|     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { |     } 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 |     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException | ||||||
|         | InvalidOperationException e) { |         | InvalidOperationException e) { | ||||||
|       System.out.println(e.getMessage()); |       LOGGER.error(e.getMessage()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -129,7 +133,7 @@ public class EventAsynchronousTest { | |||||||
|       assertTrue(eventManager.getEventPool().size() == 0); |       assertTrue(eventManager.getEventPool().size() == 0); | ||||||
|  |  | ||||||
|     } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { |     } 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.event.UserCreatedEvent; | ||||||
| import com.iluwatar.eda.framework.Handler; | import com.iluwatar.eda.framework.Handler; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Handles the {@link UserCreatedEvent} message. |  * Handles the {@link UserCreatedEvent} message. | ||||||
|  */ |  */ | ||||||
| public class UserCreatedEventHandler implements Handler<UserCreatedEvent> { | public class UserCreatedEventHandler implements Handler<UserCreatedEvent> { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(UserCreatedEventHandler.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void onEvent(UserCreatedEvent event) { |   public void onEvent(UserCreatedEvent event) { | ||||||
|  |     LOGGER.info("User '{}' has been Created!", event.getUser().getUsername()); | ||||||
|     System.out.println(String.format( |  | ||||||
|             "User '%s' 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.event.UserUpdatedEvent; | ||||||
| import com.iluwatar.eda.framework.Handler; | import com.iluwatar.eda.framework.Handler; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Handles the {@link UserUpdatedEvent} message. |  * Handles the {@link UserUpdatedEvent} message. | ||||||
|  */ |  */ | ||||||
| public class UserUpdatedEventHandler implements Handler<UserUpdatedEvent> { | public class UserUpdatedEventHandler implements Handler<UserUpdatedEvent> { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(UserUpdatedEventHandler.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void onEvent(UserUpdatedEvent event) { |   public void onEvent(UserUpdatedEvent event) { | ||||||
|  |     LOGGER.info("User '{}' has been Updated!", event.getUser().getUsername()); | ||||||
|     System.out.println(String.format( |  | ||||||
|             "User '%s' has been Updated!", event.getUser().getUsername())); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.facade; | package com.iluwatar.facade; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * DwarvenCartOperator is one of the goldmine subsystems. |  * DwarvenCartOperator is one of the goldmine subsystems. | ||||||
| @@ -29,9 +32,11 @@ package com.iluwatar.facade; | |||||||
|  */ |  */ | ||||||
| public class DwarvenCartOperator extends DwarvenMineWorker { | public class DwarvenCartOperator extends DwarvenMineWorker { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenCartOperator.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void work() { |   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 |   @Override | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.facade; | package com.iluwatar.facade; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * DwarvenGoldDigger is one of the goldmine subsystems. |  * DwarvenGoldDigger is one of the goldmine subsystems. | ||||||
| @@ -29,9 +32,11 @@ package com.iluwatar.facade; | |||||||
|  */ |  */ | ||||||
| public class DwarvenGoldDigger extends DwarvenMineWorker { | public class DwarvenGoldDigger extends DwarvenMineWorker { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenGoldDigger.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void work() { |   public void work() { | ||||||
|     System.out.println(name() + " digs for gold."); |     LOGGER.info("{} digs for gold.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.facade; | package com.iluwatar.facade; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * DwarvenMineWorker is one of the goldmine subsystems. |  * DwarvenMineWorker is one of the goldmine subsystems. | ||||||
| @@ -29,20 +32,22 @@ package com.iluwatar.facade; | |||||||
|  */ |  */ | ||||||
| public abstract class DwarvenMineWorker { | public abstract class DwarvenMineWorker { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenMineWorker.class); | ||||||
|  |  | ||||||
|   public void goToSleep() { |   public void goToSleep() { | ||||||
|     System.out.println(name() + " goes to sleep."); |     LOGGER.info("{} goes to sleep.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void wakeUp() { |   public void wakeUp() { | ||||||
|     System.out.println(name() + " wakes up."); |     LOGGER.info("{} wakes up.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void goHome() { |   public void goHome() { | ||||||
|     System.out.println(name() + " goes home."); |     LOGGER.info("{} goes home.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void goToMine() { |   public void goToMine() { | ||||||
|     System.out.println(name() + " goes to the mine."); |     LOGGER.info("{} goes to the mine.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private void action(Action action) { |   private void action(Action action) { | ||||||
| @@ -63,7 +68,7 @@ public abstract class DwarvenMineWorker { | |||||||
|         work(); |         work(); | ||||||
|         break; |         break; | ||||||
|       default: |       default: | ||||||
|         System.out.println("Undefined action"); |         LOGGER.info("Undefined action"); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.facade; | package com.iluwatar.facade; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * DwarvenTunnelDigger is one of the goldmine subsystems. |  * DwarvenTunnelDigger is one of the goldmine subsystems. | ||||||
| @@ -29,9 +32,11 @@ package com.iluwatar.facade; | |||||||
|  */ |  */ | ||||||
| public class DwarvenTunnelDigger extends DwarvenMineWorker { | public class DwarvenTunnelDigger extends DwarvenMineWorker { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(DwarvenTunnelDigger.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void work() { |   public void work() { | ||||||
|     System.out.println(name() + " creates another promising tunnel."); |     LOGGER.info("{} creates another promising tunnel.", name()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   | |||||||
| @@ -22,17 +22,19 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.facade; | 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.After; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | 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.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.mock; | import static org.junit.Assert.assertTrue; | ||||||
| import static org.mockito.Mockito.verify; |  | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
| import static org.mockito.internal.verification.VerificationModeFactory.times; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/9/15 - 9:40 PM |  * Date: 12/9/15 - 9:40 PM | ||||||
| @@ -41,35 +43,19 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; | |||||||
|  */ |  */ | ||||||
| public class DwarvenGoldmineFacadeTest { | public class DwarvenGoldmineFacadeTest { | ||||||
|  |  | ||||||
|   /** |   private InMemoryAppender appender; | ||||||
|    * 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); |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * 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 |   @Before | ||||||
|   public void setUp() { |   public void setUp() { | ||||||
|     System.setOut(this.stdOutMock); |     appender = new InMemoryAppender(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * Removed the mocked std-out {@link PrintStream} again from the {@link System} class |  | ||||||
|    */ |  | ||||||
|   @After |   @After | ||||||
|   public void tearDown() { |   public void tearDown() { | ||||||
|     System.setOut(this.stdOutOrig); |     appender.stop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |    /** | ||||||
|    * Test a complete day cycle in the gold mine by executing all three different steps: {@link |    * Test a complete day cycle in the gold mine by executing all three different steps: {@link | ||||||
|    * DwarvenGoldmineFacade#startNewDay()}, {@link DwarvenGoldmineFacade#digOutGold()} and {@link |    * DwarvenGoldmineFacade#startNewDay()}, {@link DwarvenGoldmineFacade#digOutGold()} and {@link | ||||||
|    * DwarvenGoldmineFacade#endDay()}. |    * DwarvenGoldmineFacade#endDay()}. | ||||||
| @@ -82,44 +68,68 @@ public class DwarvenGoldmineFacadeTest { | |||||||
|     goldMine.startNewDay(); |     goldMine.startNewDay(); | ||||||
|  |  | ||||||
|     // On the start of a day, all workers should wake up ... |     // On the start of a day, all workers should wake up ... | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger wakes up.")); |     assertTrue(appender.logContains("Dwarf gold digger wakes up.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator wakes up.")); |     assertTrue(appender.logContains("Dwarf cart operator wakes up.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger wakes up.")); |     assertTrue(appender.logContains("Dwarven tunnel digger wakes up.")); | ||||||
|  |  | ||||||
|     // ... and go to the mine |     // ... and go to the mine | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes to the mine.")); |     assertTrue(appender.logContains("Dwarf gold digger goes to the mine.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to the mine.")); |     assertTrue(appender.logContains("Dwarf cart operator goes to the mine.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger 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 |     // 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! |     // Now do some actual work, start digging gold! | ||||||
|     goldMine.digOutGold(); |     goldMine.digOutGold(); | ||||||
|  |  | ||||||
|     // Since we gave the dig command, every worker should be doing it's job ... |     // 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.")); |     assertTrue(appender.logContains("Dwarf gold digger digs for gold.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator moves gold chunks out of the mine.")); |     assertTrue(appender.logContains("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("Dwarven tunnel digger creates another promising tunnel.")); | ||||||
|  |  | ||||||
|     // Again, they shouldn't be doing anything else. |     // Again, they shouldn't be doing anything else. | ||||||
|     verifyNoMoreInteractions(this.stdOutMock); |     assertEquals(9, appender.getLogSize()); | ||||||
|  |  | ||||||
|     // Enough gold, lets end the day. |     // Enough gold, lets end the day. | ||||||
|     goldMine.endDay(); |     goldMine.endDay(); | ||||||
|  |  | ||||||
|     // Check if the workers go home ... |     // Check if the workers go home ... | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf gold digger goes home.")); |     assertTrue(appender.logContains("Dwarf gold digger goes home.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes home.")); |     assertTrue(appender.logContains("Dwarf cart operator goes home.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes home.")); |     assertTrue(appender.logContains("Dwarven tunnel digger goes home.")); | ||||||
|  |  | ||||||
|     // ... and go to sleep. We need well rested workers the next day :) |     // ... 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.")); |     assertTrue(appender.logContains("Dwarf gold digger goes to sleep.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarf cart operator goes to sleep.")); |     assertTrue(appender.logContains("Dwarf cart operator goes to sleep.")); | ||||||
|     verify(this.stdOutMock, times(1)).println(eq("Dwarven tunnel digger goes to sleep.")); |     assertTrue(appender.logContains("Dwarven tunnel digger goes to sleep.")); | ||||||
|  |  | ||||||
|     // Every worker should be sleeping now, no other actions allowed |     // 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; | 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 |  * 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 |  * 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. |  * be mapped explicitly with desired class type in the factory instance. | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point. |    * Program entry point. | ||||||
|    * |    * | ||||||
| @@ -49,6 +55,6 @@ public class App { | |||||||
|       builder.add(WeaponType.BOW, Bow::new); |       builder.add(WeaponType.BOW, Bow::new); | ||||||
|     }); |     }); | ||||||
|     Weapon axe = factory.create(WeaponType.AXE); |     Weapon axe = factory.create(WeaponType.AXE); | ||||||
|     System.out.println(axe); |     LOGGER.info(axe.toString()); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.factory.method; | 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 |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   private final Blacksmith blacksmith; |   private final Blacksmith blacksmith; | ||||||
|    |    | ||||||
|   /** |   /** | ||||||
| @@ -70,8 +75,8 @@ public class App { | |||||||
|   private void manufactureWeapons() { |   private void manufactureWeapons() { | ||||||
|     Weapon weapon; |     Weapon weapon; | ||||||
|     weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); |     weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); | ||||||
|     System.out.println(weapon); |     LOGGER.info(weapon.toString()); | ||||||
|     weapon = blacksmith.manufactureWeapon(WeaponType.AXE); |     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.pattern.propertiesversion.PropertiesFeatureToggleVersion; | ||||||
| import com.iluwatar.featuretoggle.user.User; | import com.iluwatar.featuretoggle.user.User; | ||||||
| import com.iluwatar.featuretoggle.user.UserGroup; | import com.iluwatar.featuretoggle.user.UserGroup; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Properties; | import java.util.Properties; | ||||||
|  |  | ||||||
| @@ -45,6 +47,8 @@ import java.util.Properties; | |||||||
|  */ |  */ | ||||||
| public class App { | 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 |    *  Block 1 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature | ||||||
|    *  toggle to enabled. |    *  toggle to enabled. | ||||||
| @@ -70,7 +74,7 @@ public class App { | |||||||
|     properties.put("enhancedWelcome", true); |     properties.put("enhancedWelcome", true); | ||||||
|     Service service = new PropertiesFeatureToggleVersion(properties); |     Service service = new PropertiesFeatureToggleVersion(properties); | ||||||
|     final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); |     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); |     turnedOff.put("enhancedWelcome", false); | ||||||
|     Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff); |     Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff); | ||||||
|     final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code")); |     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 welcomeMessagePaidUser = service.getWelcomeMessage(paidUser); | ||||||
|     final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser); |     final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser); | ||||||
|     System.out.println(welcomeMessageFreeUser); |     LOGGER.info(welcomeMessageFreeUser); | ||||||
|     System.out.println(welcomeMessagePaidUser); |     LOGGER.info(welcomeMessagePaidUser); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -35,6 +35,8 @@ import java.util.function.Predicate; | |||||||
| import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; | import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; | ||||||
| import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable; | import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable; | ||||||
| import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable; | 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. |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
| @@ -74,9 +78,7 @@ public class App { | |||||||
|         .fromCopyOf(integerList) |         .fromCopyOf(integerList) | ||||||
|         .filter(number -> number % 2 == 0) |         .filter(number -> number % 2 == 0) | ||||||
|         .first() |         .first() | ||||||
|         .ifPresent( |         .ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber)); | ||||||
|             evenNumber -> System.out.println(String.format("The first even number is: %d", |  | ||||||
|                 evenNumber))); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     List<String> transformedList = |     List<String> transformedList = | ||||||
| @@ -97,9 +99,7 @@ public class App { | |||||||
|         .filter(negatives()) |         .filter(negatives()) | ||||||
|         .first(2) |         .first(2) | ||||||
|         .last() |         .last() | ||||||
|         .ifPresent( |         .ifPresent(lastOfFirstTwo -> LOGGER.info("The last of the first two negatives is: {}", lastOfFirstTwo)); | ||||||
|             lastOfFirstTwo -> System.out.println(String.format( |  | ||||||
|                 "The last of the first two negatives is: %d", lastOfFirstTwo))); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static Function<Integer, String> transformToString() { |   private static Function<Integer, String> transformToString() { | ||||||
| @@ -126,6 +126,6 @@ public class App { | |||||||
|       joiner.add(iterator.next().toString()); |       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.action.Content; | ||||||
| import com.iluwatar.flux.store.ContentStore; | import com.iluwatar.flux.store.ContentStore; | ||||||
| import com.iluwatar.flux.store.Store; | 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 { | public class ContentView implements View { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ContentView.class); | ||||||
|  |  | ||||||
|   private Content content = Content.PRODUCTS; |   private Content content = Content.PRODUCTS; | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
| @@ -44,6 +48,6 @@ public class ContentView implements View { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void render() { |   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.dispatcher.Dispatcher; | ||||||
| import com.iluwatar.flux.store.MenuStore; | import com.iluwatar.flux.store.MenuStore; | ||||||
| import com.iluwatar.flux.store.Store; | 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 { | public class MenuView implements View { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(MenuView.class); | ||||||
|  |  | ||||||
|   private MenuItem selected = MenuItem.HOME; |   private MenuItem selected = MenuItem.HOME; | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
| @@ -47,9 +51,9 @@ public class MenuView implements View { | |||||||
|   public void render() { |   public void render() { | ||||||
|     for (MenuItem item : MenuItem.values()) { |     for (MenuItem item : MenuItem.values()) { | ||||||
|       if (selected.equals(item)) { |       if (selected.equals(item)) { | ||||||
|         System.out.println(String.format("* %s", item.toString())); |         LOGGER.info("* {}", item); | ||||||
|       } else { |       } else { | ||||||
|         System.out.println(item.toString()); |         LOGGER.info(item.toString()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.flyweight; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -33,6 +36,8 @@ import java.util.List; | |||||||
|  */ |  */ | ||||||
| public class AlchemistShop { | public class AlchemistShop { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class); | ||||||
|  |  | ||||||
|   private List<Potion> topShelf; |   private List<Potion> topShelf; | ||||||
|   private List<Potion> bottomShelf; |   private List<Potion> bottomShelf; | ||||||
|  |  | ||||||
| @@ -88,13 +93,13 @@ public class AlchemistShop { | |||||||
|    */ |    */ | ||||||
|   public void enumerate() { |   public void enumerate() { | ||||||
|  |  | ||||||
|     System.out.println("Enumerating top shelf potions\n"); |     LOGGER.info("Enumerating top shelf potions\n"); | ||||||
|  |  | ||||||
|     for (Potion p : topShelf) { |     for (Potion p : topShelf) { | ||||||
|       p.drink(); |       p.drink(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     System.out.println("\nEnumerating bottom shelf potions\n"); |     LOGGER.info("Enumerating bottom shelf potions\n"); | ||||||
|  |  | ||||||
|     for (Potion p : bottomShelf) { |     for (Potion p : bottomShelf) { | ||||||
|       p.drink(); |       p.drink(); | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.flyweight; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * HealingPotion |  * HealingPotion | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.flyweight; | |||||||
|  */ |  */ | ||||||
| public class HealingPotion implements Potion { | public class HealingPotion implements Potion { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(HealingPotion.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void drink() { |   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; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * HolyWaterPotion |  * HolyWaterPotion | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.flyweight; | |||||||
|  */ |  */ | ||||||
| public class HolyWaterPotion implements Potion { | public class HolyWaterPotion implements Potion { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(HolyWaterPotion.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void drink() { |   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; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * InvisibilityPotion |  * InvisibilityPotion | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.flyweight; | |||||||
|  */ |  */ | ||||||
| public class InvisibilityPotion implements Potion { | public class InvisibilityPotion implements Potion { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(InvisibilityPotion.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void drink() { |   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; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * PoisonPotion |  * PoisonPotion | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.flyweight; | |||||||
|  */ |  */ | ||||||
| public class PoisonPotion implements Potion { | public class PoisonPotion implements Potion { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(PoisonPotion.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void drink() { |   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; | package com.iluwatar.flyweight; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * StrengthPotion |  * StrengthPotion | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.flyweight; | |||||||
|  */ |  */ | ||||||
| public class StrengthPotion implements Potion { | public class StrengthPotion implements Potion { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(StrengthPotion.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void drink() { |   public void drink() { | ||||||
|     System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")"); |     LOGGER.info("You feel strong. (Potion={})", System.identityHashCode(this)); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,15 +22,20 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.front.controller; | package com.iluwatar.front.controller; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * View for archers. |  * View for archers. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class ArcherView implements View { | public class ArcherView implements View { | ||||||
|  |    | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ArcherView.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void display() { |   public void display() { | ||||||
|     System.out.println("Displaying archers"); |     LOGGER.info("Displaying archers"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.front.controller; | package com.iluwatar.front.controller; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * View for catapults. |  * View for catapults. | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.front.controller; | |||||||
|  */ |  */ | ||||||
| public class CatapultView implements View { | public class CatapultView implements View { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(CatapultView.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void display() { |   public void display() { | ||||||
|     System.out.println("Displaying catapults"); |     LOGGER.info("Displaying catapults"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.front.controller; | package com.iluwatar.front.controller; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * View for errors. |  * View for errors. | ||||||
| @@ -29,8 +32,10 @@ package com.iluwatar.front.controller; | |||||||
|  */ |  */ | ||||||
| public class ErrorView implements View { | public class ErrorView implements View { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ErrorView.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void display() { |   public void display() { | ||||||
|     System.out.println("Error 500"); |     LOGGER.error("Error 500"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.front.controller; | 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.Test; | ||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.junit.runners.Parameterized; | import org.junit.runners.Parameterized; | ||||||
| @@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.verify; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
| import static org.mockito.Mockito.verifyZeroInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/13/15 - 1:39 PM |  * Date: 12/13/15 - 1:39 PM | ||||||
| @@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions; | |||||||
|  * @author Jeroen Meulemeester |  * @author Jeroen Meulemeester | ||||||
|  */ |  */ | ||||||
| @RunWith(Parameterized.class) | @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 |   @Parameters | ||||||
|   public static List<Object[]> data() { |   public static List<Object[]> data() { | ||||||
| @@ -75,10 +88,10 @@ public class CommandTest extends StdOutTest { | |||||||
|   @Test |   @Test | ||||||
|   public void testDisplay() { |   public void testDisplay() { | ||||||
|     final FrontController frontController = new FrontController(); |     final FrontController frontController = new FrontController(); | ||||||
|     verifyZeroInteractions(getStdOutMock()); |     assertEquals(0, appender.getLogSize()); | ||||||
|     frontController.handleRequest(request); |     frontController.handleRequest(request); | ||||||
|     verify(getStdOutMock()).println(displayMessage); |     assertEquals(displayMessage, appender.getLastMessage()); | ||||||
|     verifyNoMoreInteractions(getStdOutMock()); |     assertEquals(1, appender.getLogSize()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.front.controller; | 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.Test; | ||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.junit.runners.Parameterized; | import org.junit.runners.Parameterized; | ||||||
| @@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.verify; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
| import static org.mockito.Mockito.verifyZeroInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/13/15 - 1:39 PM |  * Date: 12/13/15 - 1:39 PM | ||||||
| @@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions; | |||||||
|  * @author Jeroen Meulemeester |  * @author Jeroen Meulemeester | ||||||
|  */ |  */ | ||||||
| @RunWith(Parameterized.class) | @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 |   @Parameters | ||||||
|   public static List<Object[]> data() { |   public static List<Object[]> data() { | ||||||
| @@ -74,10 +87,10 @@ public class FrontControllerTest extends StdOutTest { | |||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   public void testDisplay() { |   public void testDisplay() { | ||||||
|     verifyZeroInteractions(getStdOutMock()); |     assertEquals(0, appender.getLogSize()); | ||||||
|     this.command.process(); |     this.command.process(); | ||||||
|     verify(getStdOutMock()).println(displayMessage); |     assertEquals(displayMessage, appender.getLastMessage()); | ||||||
|     verifyNoMoreInteractions(getStdOutMock()); |     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; | 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.Test; | ||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.junit.runners.Parameterized; | import org.junit.runners.Parameterized; | ||||||
| @@ -30,9 +33,7 @@ import org.junit.runners.Parameterized.Parameters; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import static org.mockito.Mockito.verify; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
| import static org.mockito.Mockito.verifyZeroInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/13/15 - 1:39 PM |  * Date: 12/13/15 - 1:39 PM | ||||||
| @@ -40,7 +41,19 @@ import static org.mockito.Mockito.verifyZeroInteractions; | |||||||
|  * @author Jeroen Meulemeester |  * @author Jeroen Meulemeester | ||||||
|  */ |  */ | ||||||
| @RunWith(Parameterized.class) | @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 |   @Parameters | ||||||
|   public static List<Object[]> data() { |   public static List<Object[]> data() { | ||||||
| @@ -74,10 +87,10 @@ public class ViewTest extends StdOutTest { | |||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   public void testDisplay() { |   public void testDisplay() { | ||||||
|     verifyZeroInteractions(getStdOutMock()); |     assertEquals(0, appender.getLogSize()); | ||||||
|     this.view.display(); |     this.view.display(); | ||||||
|     verify(getStdOutMock()).println(displayMessage); |     assertEquals(displayMessage, appender.getLastMessage()); | ||||||
|     verifyNoMoreInteractions(getStdOutMock()); |     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; | package com.iluwatar.halfsynchalfasync; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.concurrent.LinkedBlockingQueue; | import java.util.concurrent.LinkedBlockingQueue; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -66,6 +69,8 @@ import java.util.concurrent.LinkedBlockingQueue; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -128,7 +133,7 @@ public class App { | |||||||
|     @Override |     @Override | ||||||
|     public void onPostCall(Long result) { |     public void onPostCall(Long result) { | ||||||
|       // Handle the result of computation |       // Handle the result of computation | ||||||
|       System.out.println(result); |       LOGGER.info(result.toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -141,7 +146,7 @@ public class App { | |||||||
|     try { |     try { | ||||||
|       Thread.sleep(i); |       Thread.sleep(i); | ||||||
|     } catch (InterruptedException e) { |     } catch (InterruptedException e) { | ||||||
|       System.out.println(e); |       LOGGER.error("Exception caught.", e); | ||||||
|     } |     } | ||||||
|     return i * (i + 1) / 2; |     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.module.LotteryModule; | ||||||
| import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; | import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; | ||||||
| import com.iluwatar.hexagonal.sampledata.SampleData; | import com.iluwatar.hexagonal.sampledata.SampleData; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Scanner; | import java.util.Scanner; | ||||||
|  |  | ||||||
| @@ -38,6 +40,8 @@ import java.util.Scanner; | |||||||
|  */ |  */ | ||||||
| public class ConsoleAdministration { | public class ConsoleAdministration { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleAdministration.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
| @@ -53,29 +57,29 @@ public class ConsoleAdministration { | |||||||
|       printMainMenu(); |       printMainMenu(); | ||||||
|       String cmd = readString(scanner); |       String cmd = readString(scanner); | ||||||
|       if (cmd.equals("1")) { |       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")) { |       } else if (cmd.equals("2")) { | ||||||
|         LotteryNumbers numbers = administartion.performLottery(); |         LotteryNumbers numbers = administartion.performLottery(); | ||||||
|         System.out.println("The winning numbers: " + numbers.getNumbersAsString()); |         LOGGER.info("The winning numbers: {}", numbers.getNumbersAsString()); | ||||||
|         System.out.println("Time to reset the database for next round, eh?"); |         LOGGER.info("Time to reset the database for next round, eh?"); | ||||||
|       } else if (cmd.equals("3")) { |       } else if (cmd.equals("3")) { | ||||||
|         administartion.resetLottery(); |         administartion.resetLottery(); | ||||||
|         System.out.println("The lottery ticket database was cleared."); |         LOGGER.info("The lottery ticket database was cleared."); | ||||||
|       } else if (cmd.equals("4")) { |       } else if (cmd.equals("4")) { | ||||||
|         exit = true; |         exit = true; | ||||||
|       } else { |       } else { | ||||||
|         System.out.println("Unknown command: " + cmd); |         LOGGER.info("Unknown command: {}", cmd); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static void printMainMenu() { |   private static void printMainMenu() { | ||||||
|     System.out.println(""); |     LOGGER.info(""); | ||||||
|     System.out.println("### Lottery Administration Console ###"); |     LOGGER.info("### Lottery Administration Console ###"); | ||||||
|     System.out.println("(1) Show all submitted tickets"); |     LOGGER.info("(1) Show all submitted tickets"); | ||||||
|     System.out.println("(2) Perform lottery draw"); |     LOGGER.info("(2) Perform lottery draw"); | ||||||
|     System.out.println("(3) Reset lottery ticket database"); |     LOGGER.info("(3) Reset lottery ticket database"); | ||||||
|     System.out.println("(4) Exit"); |     LOGGER.info("(4) Exit"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static String readString(Scanner scanner) { |   private static String readString(Scanner scanner) { | ||||||
|   | |||||||
| @@ -23,42 +23,42 @@ | |||||||
| package com.iluwatar.hexagonal.eventlog; | package com.iluwatar.hexagonal.eventlog; | ||||||
|  |  | ||||||
| import com.iluwatar.hexagonal.domain.PlayerDetails; | import com.iluwatar.hexagonal.domain.PlayerDetails; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Standard output event log |  * Standard output event log | ||||||
|  */ |  */ | ||||||
| public class StdOutEventLog implements LotteryEventLog { | public class StdOutEventLog implements LotteryEventLog { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(StdOutEventLog.class); | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void ticketSubmitted(PlayerDetails details) { |   public void ticketSubmitted(PlayerDetails details) { | ||||||
|     System.out.println(String.format("Lottery ticket for %s was submitted. Bank account %s was charged for 3 credits.", |     LOGGER.info("Lottery ticket for {} was submitted. Bank account {} was charged for 3 credits.", | ||||||
|         details.getEmail(), details.getBankAccount())); |         details.getEmail(), details.getBankAccount()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void ticketDidNotWin(PlayerDetails details) { |   public void ticketDidNotWin(PlayerDetails details) { | ||||||
|     System.out.println(String.format("Lottery ticket for %s was checked and unfortunately did not win this time.", |     LOGGER.info("Lottery ticket for {} was checked and unfortunately did not win this time.", details.getEmail()); | ||||||
|         details.getEmail())); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void ticketWon(PlayerDetails details, int prizeAmount) { |   public void ticketWon(PlayerDetails details, int prizeAmount) { | ||||||
|     System.out |     LOGGER.info("Lottery ticket for {} has won! The bank account {} was deposited with {} credits.", | ||||||
|         .println(String.format("Lottery ticket for %s has won! The bank account %s was deposited with %d credits.", |             details.getEmail(), details.getBankAccount(), prizeAmount); | ||||||
|             details.getEmail(), details.getBankAccount(), prizeAmount)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void prizeError(PlayerDetails details, int prizeAmount) { |   public void prizeError(PlayerDetails details, int prizeAmount) { | ||||||
|     System.out |     LOGGER.error("Lottery ticket for {} has won! Unfortunately the bank credit transfer of {} failed.", | ||||||
|         .println(String.format("Lottery ticket for %s has won! Unfortunately the bank credit transfer of %d failed.", |             details.getEmail(), prizeAmount); | ||||||
|             details.getEmail(), prizeAmount)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void ticketSubmitError(PlayerDetails details) { |   public void ticketSubmitError(PlayerDetails details) { | ||||||
|     System.out.println( |     LOGGER.error("Lottery ticket for {} could not be submitted because the credit transfer of 3 credits failed.", | ||||||
|         String.format("Lottery ticket for %s could not be submitted because the credit transfer of 3 credits failed.", |             details.getEmail()); | ||||||
|             details.getEmail())); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -33,6 +33,8 @@ import com.iluwatar.hexagonal.domain.LotteryTicketId; | |||||||
| import com.iluwatar.hexagonal.domain.PlayerDetails; | import com.iluwatar.hexagonal.domain.PlayerDetails; | ||||||
| import com.iluwatar.hexagonal.module.LotteryModule; | import com.iluwatar.hexagonal.module.LotteryModule; | ||||||
| import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; | import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Optional; | import java.util.Optional; | ||||||
| @@ -44,6 +46,7 @@ import java.util.Set; | |||||||
|  */ |  */ | ||||||
| public class ConsoleLottery { | public class ConsoleLottery { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleLottery.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
| @@ -59,25 +62,25 @@ public class ConsoleLottery { | |||||||
|       printMainMenu(); |       printMainMenu(); | ||||||
|       String cmd = readString(scanner); |       String cmd = readString(scanner); | ||||||
|       if (cmd.equals("1")) { |       if (cmd.equals("1")) { | ||||||
|         System.out.println("What is the account number?"); |         LOGGER.info("What is the account number?"); | ||||||
|         String account = readString(scanner); |         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")) { |       } else if (cmd.equals("2")) { | ||||||
|         System.out.println("What is the account number?"); |         LOGGER.info("What is the account number?"); | ||||||
|         String account = readString(scanner); |         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); |         String amount = readString(scanner); | ||||||
|         bank.setFunds(account, Integer.parseInt(amount)); |         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")) { |       } else if (cmd.equals("3")) { | ||||||
|         System.out.println("What is your email address?"); |         LOGGER.info("What is your email address?"); | ||||||
|         String email = readString(scanner); |         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); |         String account = readString(scanner); | ||||||
|         System.out.println("What is your phone number?"); |         LOGGER.info("What is your phone number?"); | ||||||
|         String phone = readString(scanner); |         String phone = readString(scanner); | ||||||
|         PlayerDetails details = new PlayerDetails(email, account, phone); |         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); |         String numbers = readString(scanner); | ||||||
|         try { |         try { | ||||||
|           String[] parts = numbers.split(","); |           String[] parts = numbers.split(","); | ||||||
| @@ -89,17 +92,17 @@ public class ConsoleLottery { | |||||||
|           LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers); |           LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers); | ||||||
|           Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket); |           Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket); | ||||||
|           if (id.isPresent()) { |           if (id.isPresent()) { | ||||||
|             System.out.println("Submitted lottery ticket with id: " + id.get()); |             LOGGER.info("Submitted lottery ticket with id: {}", id.get()); | ||||||
|           } else { |           } else { | ||||||
|             System.out.println("Failed submitting lottery ticket - please try again."); |             LOGGER.info("Failed submitting lottery ticket - please try again."); | ||||||
|           } |           } | ||||||
|         } catch (Exception e) { |         } 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")) { |       } 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); |         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); |         String numbers = readString(scanner); | ||||||
|         try { |         try { | ||||||
|           String[] parts = numbers.split(","); |           String[] parts = numbers.split(","); | ||||||
| @@ -110,31 +113,31 @@ public class ConsoleLottery { | |||||||
|           LotteryTicketCheckResult result = service.checkTicketForPrize( |           LotteryTicketCheckResult result = service.checkTicketForPrize( | ||||||
|               new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers)); |               new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers)); | ||||||
|           if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) { |           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)) { |           } 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 { |           } else { | ||||||
|             System.out.println("Such lottery ticket has not been submitted."); |             LOGGER.info("Such lottery ticket has not been submitted."); | ||||||
|           } |           } | ||||||
|         } catch (Exception e) { |         } 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")) { |       } else if (cmd.equals("5")) { | ||||||
|         exit = true; |         exit = true; | ||||||
|       } else { |       } else { | ||||||
|         System.out.println("Unknown command"); |         LOGGER.info("Unknown command"); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static void printMainMenu() { |   private static void printMainMenu() { | ||||||
|     System.out.println(""); |     LOGGER.info(""); | ||||||
|     System.out.println("### Lottery Service Console ###"); |     LOGGER.info("### Lottery Service Console ###"); | ||||||
|     System.out.println("(1) Query lottery account funds"); |     LOGGER.info("(1) Query lottery account funds"); | ||||||
|     System.out.println("(2) Add funds to lottery account"); |     LOGGER.info("(2) Add funds to lottery account"); | ||||||
|     System.out.println("(3) Submit ticket"); |     LOGGER.info("(3) Submit ticket"); | ||||||
|     System.out.println("(4) Check ticket"); |     LOGGER.info("(4) Check ticket"); | ||||||
|     System.out.println("(5) Exit"); |     LOGGER.info("(5) Exit"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static String readString(Scanner scanner) { |   private static String readString(Scanner scanner) { | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.interpreter; | package com.iluwatar.interpreter; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Stack; | import java.util.Stack; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -37,6 +40,8 @@ import java.util.Stack; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    *  |    *  | ||||||
|    * Program entry point. |    * Program entry point. | ||||||
| @@ -56,21 +61,21 @@ public class App { | |||||||
|       if (isOperator(s)) { |       if (isOperator(s)) { | ||||||
|         Expression rightExpression = stack.pop(); |         Expression rightExpression = stack.pop(); | ||||||
|         Expression leftExpression = stack.pop(); |         Expression leftExpression = stack.pop(); | ||||||
|         System.out.println(String.format("popped from stack left: %d right: %d", |         LOGGER.info("popped from stack left: {} right: {}", | ||||||
|             leftExpression.interpret(), rightExpression.interpret())); |             leftExpression.interpret(), rightExpression.interpret()); | ||||||
|         Expression operator = getOperatorInstance(s, leftExpression, rightExpression); |         Expression operator = getOperatorInstance(s, leftExpression, rightExpression); | ||||||
|         System.out.println(String.format("operator: %s", operator)); |         LOGGER.info("operator: {}", operator); | ||||||
|         int result = operator.interpret(); |         int result = operator.interpret(); | ||||||
|         NumberExpression resultExpression = new NumberExpression(result); |         NumberExpression resultExpression = new NumberExpression(result); | ||||||
|         stack.push(resultExpression); |         stack.push(resultExpression); | ||||||
|         System.out.println(String.format("push result to stack: %d", resultExpression.interpret())); |         LOGGER.info("push result to stack: {}", resultExpression.interpret()); | ||||||
|       } else { |       } else { | ||||||
|         Expression i = new NumberExpression(s); |         Expression i = new NumberExpression(s); | ||||||
|         stack.push(i); |         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) { |   public static boolean isOperator(String s) { | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.iterator; | 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 |  * 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 { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -44,28 +49,28 @@ public class App { | |||||||
|  |  | ||||||
|     ItemIterator ringIterator = chest.iterator(ItemType.RING); |     ItemIterator ringIterator = chest.iterator(ItemType.RING); | ||||||
|     while (ringIterator.hasNext()) { |     while (ringIterator.hasNext()) { | ||||||
|       System.out.println(ringIterator.next()); |       LOGGER.info(ringIterator.next().toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     System.out.println("----------"); |     LOGGER.info("----------"); | ||||||
|  |  | ||||||
|     ItemIterator potionIterator = chest.iterator(ItemType.POTION); |     ItemIterator potionIterator = chest.iterator(ItemType.POTION); | ||||||
|     while (potionIterator.hasNext()) { |     while (potionIterator.hasNext()) { | ||||||
|       System.out.println(potionIterator.next()); |       LOGGER.info(potionIterator.next().toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     System.out.println("----------"); |     LOGGER.info("----------"); | ||||||
|  |  | ||||||
|     ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON); |     ItemIterator weaponIterator = chest.iterator(ItemType.WEAPON); | ||||||
|     while (weaponIterator.hasNext()) { |     while (weaponIterator.hasNext()) { | ||||||
|       System.out.println(weaponIterator.next()); |       LOGGER.info(weaponIterator.next().toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     System.out.println("----------"); |     LOGGER.info("----------"); | ||||||
|  |  | ||||||
|     ItemIterator it = chest.iterator(ItemType.ANY); |     ItemIterator it = chest.iterator(ItemType.ANY); | ||||||
|     while (it.hasNext()) { |     while (it.hasNext()) { | ||||||
|       System.out.println(it.next()); |       LOGGER.info(it.next().toString()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.layers; | package com.iluwatar.layers; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * View implementation for displaying cakes |  * View implementation for displaying cakes | ||||||
| @@ -29,6 +32,8 @@ package com.iluwatar.layers; | |||||||
|  */ |  */ | ||||||
| public class CakeViewImpl implements View { | public class CakeViewImpl implements View { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class); | ||||||
|  |  | ||||||
|   private CakeBakingService cakeBakingService; |   private CakeBakingService cakeBakingService; | ||||||
|  |  | ||||||
|   public CakeViewImpl(CakeBakingService cakeBakingService) { |   public CakeViewImpl(CakeBakingService cakeBakingService) { | ||||||
| @@ -36,6 +41,6 @@ public class CakeViewImpl implements View { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void render() { |   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; | 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.junit.Test; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.LinkedList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.*; | import static org.mockito.Mockito.*; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -34,7 +42,19 @@ import static org.mockito.Mockito.*; | |||||||
|  * |  * | ||||||
|  * @author Jeroen Meulemeester |  * @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 |    * Verify if the cake view renders the expected result | ||||||
| @@ -56,11 +76,34 @@ public class CakeViewImplTest extends StdOutTest { | |||||||
|  |  | ||||||
|     final CakeViewImpl cakeView = new CakeViewImpl(bakingService); |     final CakeViewImpl cakeView = new CakeViewImpl(bakingService); | ||||||
|  |  | ||||||
|     verifyZeroInteractions(getStdOutMock()); |     assertEquals(0, appender.getLogSize()); | ||||||
|  |  | ||||||
|     cakeView.render(); |     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; | package com.iluwatar.lazy.loading; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Lazy loading idiom defers object creation until needed. |  * Lazy loading idiom defers object creation until needed. | ||||||
| @@ -33,6 +36,9 @@ package com.iluwatar.lazy.loading; | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    *  |    *  | ||||||
| @@ -43,16 +49,16 @@ public class App { | |||||||
|     // Simple lazy loader - not thread safe |     // Simple lazy loader - not thread safe | ||||||
|     HolderNaive holderNaive = new HolderNaive(); |     HolderNaive holderNaive = new HolderNaive(); | ||||||
|     Heavy heavy = holderNaive.getHeavy(); |     Heavy heavy = holderNaive.getHeavy(); | ||||||
|     System.out.println("heavy=" + heavy); |     LOGGER.info("heavy={}", heavy); | ||||||
|  |  | ||||||
|     // Thread safe lazy loader, but with heavy synchronization on each access |     // Thread safe lazy loader, but with heavy synchronization on each access | ||||||
|     HolderThreadSafe holderThreadSafe = new HolderThreadSafe(); |     HolderThreadSafe holderThreadSafe = new HolderThreadSafe(); | ||||||
|     Heavy another = holderThreadSafe.getHeavy(); |     Heavy another = holderThreadSafe.getHeavy(); | ||||||
|     System.out.println("another=" + another); |     LOGGER.info("another={}", another); | ||||||
|  |  | ||||||
|     // The most efficient lazy loader utilizing Java 8 features |     // The most efficient lazy loader utilizing Java 8 features | ||||||
|     Java8Holder java8Holder = new Java8Holder(); |     Java8Holder java8Holder = new Java8Holder(); | ||||||
|     Heavy next = java8Holder.getHeavy(); |     Heavy next = java8Holder.getHeavy(); | ||||||
|     System.out.println("next=" + next); |     LOGGER.info("next={}", next); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.lazy.loading; | package com.iluwatar.lazy.loading; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Heavy objects are expensive to create. |  * Heavy objects are expensive to create. | ||||||
| @@ -29,16 +32,18 @@ package com.iluwatar.lazy.loading; | |||||||
|  */ |  */ | ||||||
| public class Heavy { | public class Heavy { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Heavy.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Constructor |    * Constructor | ||||||
|    */ |    */ | ||||||
|   public Heavy() { |   public Heavy() { | ||||||
|     System.out.println("Creating Heavy ..."); |     LOGGER.info("Creating Heavy ..."); | ||||||
|     try { |     try { | ||||||
|       Thread.sleep(1000); |       Thread.sleep(1000); | ||||||
|     } catch (InterruptedException e) { |     } 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; | 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. |  * 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 { | public class HolderNaive { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(HolderNaive.class); | ||||||
|  |  | ||||||
|   private Heavy heavy; |   private Heavy heavy; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Constructor |    * Constructor | ||||||
|    */ |    */ | ||||||
|   public HolderNaive() { |   public HolderNaive() { | ||||||
|     System.out.println("HolderNaive created"); |     LOGGER.info("HolderNaive created"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.lazy.loading; | 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 |  * 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 { | public class HolderThreadSafe { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(HolderThreadSafe.class); | ||||||
|  |  | ||||||
|   private Heavy heavy; |   private Heavy heavy; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Constructor |    * Constructor | ||||||
|    */ |    */ | ||||||
|   public HolderThreadSafe() { |   public HolderThreadSafe() { | ||||||
|     System.out.println("HolderThreadSafe created"); |     LOGGER.info("HolderThreadSafe created"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.lazy.loading; | package com.iluwatar.lazy.loading; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.function.Supplier; | import java.util.function.Supplier; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -32,10 +35,12 @@ import java.util.function.Supplier; | |||||||
|  */ |  */ | ||||||
| public class Java8Holder { | public class Java8Holder { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(Java8Holder.class); | ||||||
|  |  | ||||||
|   private Supplier<Heavy> heavy = () -> createAndCacheHeavy(); |   private Supplier<Heavy> heavy = () -> createAndCacheHeavy(); | ||||||
|  |  | ||||||
|   public Java8Holder() { |   public Java8Holder() { | ||||||
|     System.out.println("Java8Holder created"); |     LOGGER.info("Java8Holder created"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public Heavy getHeavy() { |   public Heavy getHeavy() { | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.mediator; | package com.iluwatar.mediator; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  *  | ||||||
|  * Abstract base class for party members. |  * Abstract base class for party members. | ||||||
| @@ -29,23 +32,25 @@ package com.iluwatar.mediator; | |||||||
|  */ |  */ | ||||||
| public abstract class PartyMemberBase implements PartyMember { | public abstract class PartyMemberBase implements PartyMember { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(PartyMemberBase.class); | ||||||
|  |  | ||||||
|   protected Party party; |   protected Party party; | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void joinedParty(Party party) { |   public void joinedParty(Party party) { | ||||||
|     System.out.println(this + " joins the party"); |     LOGGER.info("{} joins the party", this); | ||||||
|     this.party = party; |     this.party = party; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void partyAction(Action action) { |   public void partyAction(Action action) { | ||||||
|     System.out.println(this + " " + action.getDescription()); |     LOGGER.info("{} {}", this, action.getDescription()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void act(Action action) { |   public void act(Action action) { | ||||||
|     if (party != null) { |     if (party != null) { | ||||||
|       System.out.println(this + " " + action.toString()); |       LOGGER.info("{} {}", this, action); | ||||||
|       party.act(this, action); |       party.act(this, action); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -22,22 +22,25 @@ | |||||||
|  */ |  */ | ||||||
| package com.iluwatar.mediator; | 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.After; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||||
| import org.junit.runners.Parameterized; | import org.junit.runners.Parameterized; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.io.PrintStream; |  | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
|  | import java.util.LinkedList; | ||||||
|  | import java.util.List; | ||||||
| import java.util.function.Supplier; | import java.util.function.Supplier; | ||||||
|  |  | ||||||
| import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||||
| import static org.mockito.Mockito.verify; | import static org.mockito.Mockito.verify; | ||||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; |  | ||||||
| import static org.mockito.Mockito.verifyZeroInteractions; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Date: 12/19/15 - 10:13 PM |  * 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 |    * The factory, used to create a new instance of the tested party member | ||||||
|    */ |    */ | ||||||
| @@ -99,6 +74,18 @@ public class PartyMemberTest { | |||||||
|     this.memberSupplier = memberSupplier; |     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 |    * 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()) { |     for (final Action action : Action.values()) { | ||||||
|       member.partyAction(action); |       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(); |     final PartyMember member = this.memberSupplier.get(); | ||||||
|  |  | ||||||
|     member.act(Action.GOLD); |     member.act(Action.GOLD); | ||||||
|     verifyZeroInteractions(this.stdOutMock); |     assertEquals(0, appender.getLogSize()); | ||||||
|  |  | ||||||
|     final Party party = mock(Party.class); |     final Party party = mock(Party.class); | ||||||
|     member.joinedParty(party); |     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()) { |     for (final Action action : Action.values()) { | ||||||
|       member.act(action); |       member.act(action); | ||||||
|       verify(this.stdOutMock).println(member.toString() + " " + action.toString()); |       assertEquals(member.toString() + " " + action.toString(), appender.getLastMessage()); | ||||||
|       verify(party).act(member, action); |       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()); |     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; | package com.iluwatar.memento; | ||||||
|  |  | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.Stack; | import java.util.Stack; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -45,6 +48,8 @@ import java.util.Stack; | |||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|  |   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point | ||||||
|    */ |    */ | ||||||
| @@ -52,22 +57,22 @@ public class App { | |||||||
|     Stack<StarMemento> states = new Stack<>(); |     Stack<StarMemento> states = new Stack<>(); | ||||||
|  |  | ||||||
|     Star star = new Star(StarType.SUN, 10000000, 500000); |     Star star = new Star(StarType.SUN, 10000000, 500000); | ||||||
|     System.out.println(star); |     LOGGER.info(star.toString()); | ||||||
|     states.add(star.getMemento()); |     states.add(star.getMemento()); | ||||||
|     star.timePasses(); |     star.timePasses(); | ||||||
|     System.out.println(star); |     LOGGER.info(star.toString()); | ||||||
|     states.add(star.getMemento()); |     states.add(star.getMemento()); | ||||||
|     star.timePasses(); |     star.timePasses(); | ||||||
|     System.out.println(star); |     LOGGER.info(star.toString()); | ||||||
|     states.add(star.getMemento()); |     states.add(star.getMemento()); | ||||||
|     star.timePasses(); |     star.timePasses(); | ||||||
|     System.out.println(star); |     LOGGER.info(star.toString()); | ||||||
|     states.add(star.getMemento()); |     states.add(star.getMemento()); | ||||||
|     star.timePasses(); |     star.timePasses(); | ||||||
|     System.out.println(star); |     LOGGER.info(star.toString()); | ||||||
|     while (states.size() > 0) { |     while (states.size() > 0) { | ||||||
|       star.setMemento(states.pop()); |       star.setMemento(states.pop()); | ||||||
|       System.out.println(star); |       LOGGER.info(star.toString()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user