Resolves checkstyle errors for business-delegate, bytecode, caching (#1059)
* Reduces checkstyle errors in business-delegate * Reduces checkstyle errors in bytecode * Reduces checkstyle errors in caching
This commit is contained in:
		
				
					committed by
					
						
						Ilkka Seppälä
					
				
			
			
				
	
			
			
			
						parent
						
							6d1c0b1563
						
					
				
				
					commit
					efc17fcc70
				
			@@ -28,11 +28,11 @@ package com.iluwatar.business.delegate;
 | 
			
		||||
 * tiers. By using the pattern we gain loose coupling between the tiers. The Business Delegate
 | 
			
		||||
 * encapsulates knowledge about how to locate, connect to, and interact with the business objects
 | 
			
		||||
 * that make up the application.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Some of the services the Business Delegate uses are instantiated directly, and some can be
 | 
			
		||||
 * retrieved through service lookups. The Business Delegate itself may contain business logic too
 | 
			
		||||
 * potentially tying together multiple service calls, exception handling, retrying etc.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * <p>In this example the client ({@link Client}) utilizes a business delegate (
 | 
			
		||||
 * {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
 | 
			
		||||
 * service and makes the service call.
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
package com.iluwatar.business.delegate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * BusinessDelegate separates the presentation and business tiers
 | 
			
		||||
 * BusinessDelegate separates the presentation and business tiers.
 | 
			
		||||
 */
 | 
			
		||||
public class BusinessDelegate {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,8 @@ public class BusinessLookup {
 | 
			
		||||
  private JmsService jmsService;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets service instance based on service type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param serviceType Type of service instance to be returned.
 | 
			
		||||
   * @return Service instance.
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,7 @@
 | 
			
		||||
package com.iluwatar.business.delegate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Interface for service implementations
 | 
			
		||||
 *
 | 
			
		||||
 * Interface for service implementations.
 | 
			
		||||
 */
 | 
			
		||||
public interface BusinessService {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,7 @@
 | 
			
		||||
package com.iluwatar.business.delegate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Client utilizes BusinessDelegate to call the business tier
 | 
			
		||||
 *
 | 
			
		||||
 * Client utilizes BusinessDelegate to call the business tier.
 | 
			
		||||
 */
 | 
			
		||||
public class Client {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,9 +27,7 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Service EJB implementation
 | 
			
		||||
 *
 | 
			
		||||
 * Service EJB implementation.
 | 
			
		||||
 */
 | 
			
		||||
public class EjbService implements BusinessService {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,9 +27,7 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Service JMS implementation
 | 
			
		||||
 *
 | 
			
		||||
 * Service JMS implementation.
 | 
			
		||||
 */
 | 
			
		||||
public class JmsService implements BusinessService {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,7 @@
 | 
			
		||||
package com.iluwatar.business.delegate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Enumeration for service types
 | 
			
		||||
 *
 | 
			
		||||
 * Enumeration for service types.
 | 
			
		||||
 */
 | 
			
		||||
public enum ServiceType {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,57 +24,59 @@
 | 
			
		||||
package com.iluwatar.bytecode;
 | 
			
		||||
 | 
			
		||||
import com.iluwatar.bytecode.util.InstructionConverterUtil;
 | 
			
		||||
import java.util.Stack;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The intention of Bytecode pattern is to give behavior the flexibility of data by encoding it as instructions
 | 
			
		||||
 * for a virtual machine.
 | 
			
		||||
 * An instruction set defines the low-level operations that can be performed. A series of instructions is encoded as
 | 
			
		||||
 * a sequence of bytes. A virtual machine executes these instructions one at a time,
 | 
			
		||||
 * using a stack for intermediate values. By combining instructions, complex high-level behavior can be defined.
 | 
			
		||||
 *
 | 
			
		||||
 * This pattern should be used when there is a need to define high number of behaviours and implementation engine
 | 
			
		||||
 * is not a good choice because
 | 
			
		||||
 * It is too lowe level
 | 
			
		||||
 * Iterating on it takes too long due to slow compile times or other tooling issues.
 | 
			
		||||
 * It has too much trust. If you want to ensure the behavior being defined can’t break the game,
 | 
			
		||||
 * you need to sandbox it from the rest of the codebase.
 | 
			
		||||
 * The intention of Bytecode pattern is to give behavior the flexibility of data by encoding it as
 | 
			
		||||
 * instructions for a virtual machine. An instruction set defines the low-level operations that can
 | 
			
		||||
 * be performed. A series of instructions is encoded as a sequence of bytes. A virtual machine
 | 
			
		||||
 * executes these instructions one at a time, using a stack for intermediate values. By combining
 | 
			
		||||
 * instructions, complex high-level behavior can be defined.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This pattern should be used when there is a need to define high number of behaviours and
 | 
			
		||||
 * implementation engine is not a good choice because It is too lowe level Iterating on it takes too
 | 
			
		||||
 * long due to slow compile times or other tooling issues. It has too much trust. If you want to
 | 
			
		||||
 * ensure the behavior being defined can’t break the game, you need to sandbox it from the rest of
 | 
			
		||||
 * the codebase.
 | 
			
		||||
 */
 | 
			
		||||
public class App {
 | 
			
		||||
  private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Main app method
 | 
			
		||||
   * Main app method.
 | 
			
		||||
   *
 | 
			
		||||
   * @param args command line args
 | 
			
		||||
   */
 | 
			
		||||
  public static void main(String[] args) {
 | 
			
		||||
    VirtualMachine vm = new VirtualMachine();
 | 
			
		||||
 | 
			
		||||
    Wizard wizard = new Wizard();
 | 
			
		||||
    wizard.setHealth(45);
 | 
			
		||||
    wizard.setAgility(7);
 | 
			
		||||
    wizard.setWisdom(11);
 | 
			
		||||
 | 
			
		||||
    VirtualMachine vm = new VirtualMachine();
 | 
			
		||||
    vm.getWizards()[0] = wizard;
 | 
			
		||||
 | 
			
		||||
    interpretInstruction("LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction( "LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction( "GET_HEALTH", vm);
 | 
			
		||||
    interpretInstruction( "LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction( "GET_AGILITY", vm);
 | 
			
		||||
    interpretInstruction( "LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction( "GET_WISDOM ", vm);
 | 
			
		||||
    interpretInstruction( "ADD", vm);
 | 
			
		||||
    interpretInstruction( "LITERAL 2", vm);
 | 
			
		||||
    interpretInstruction( "DIVIDE", vm);
 | 
			
		||||
    interpretInstruction( "ADD", vm);
 | 
			
		||||
    interpretInstruction( "SET_HEALTH", vm);
 | 
			
		||||
    interpretInstruction("LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction("GET_HEALTH", vm);
 | 
			
		||||
    interpretInstruction("LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction("GET_AGILITY", vm);
 | 
			
		||||
    interpretInstruction("LITERAL 0", vm);
 | 
			
		||||
    interpretInstruction("GET_WISDOM ", vm);
 | 
			
		||||
    interpretInstruction("ADD", vm);
 | 
			
		||||
    interpretInstruction("LITERAL 2", vm);
 | 
			
		||||
    interpretInstruction("DIVIDE", vm);
 | 
			
		||||
    interpretInstruction("ADD", vm);
 | 
			
		||||
    interpretInstruction("SET_HEALTH", vm);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void interpretInstruction(String instruction, VirtualMachine vm) {
 | 
			
		||||
    InstructionConverterUtil converter = new InstructionConverterUtil();
 | 
			
		||||
    vm.execute(converter.convertToByteCode(instruction));
 | 
			
		||||
    LOGGER.info(instruction + String.format("%" + (12 - instruction.length()) + "s", "" ) + vm.getStack());
 | 
			
		||||
    Stack<Integer> stack = vm.getStack();
 | 
			
		||||
    LOGGER.info(instruction + String.format("%" + (12 - instruction.length()) + "s", "") + stack);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
package com.iluwatar.bytecode;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of instructions understandable by virtual machine
 | 
			
		||||
 * Representation of instructions understandable by virtual machine.
 | 
			
		||||
 */
 | 
			
		||||
public enum Instruction {
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +51,8 @@ public enum Instruction {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Converts integer value to Instruction
 | 
			
		||||
   * Converts integer value to Instruction.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value value of instruction
 | 
			
		||||
   * @return representation of the instruction
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ package com.iluwatar.bytecode;
 | 
			
		||||
import java.util.Stack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of virtual machine
 | 
			
		||||
 * Implementation of virtual machine.
 | 
			
		||||
 */
 | 
			
		||||
public class VirtualMachine {
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +35,7 @@ public class VirtualMachine {
 | 
			
		||||
  private Wizard[] wizards = new Wizard[2];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructor
 | 
			
		||||
   * Constructor.
 | 
			
		||||
   */
 | 
			
		||||
  public VirtualMachine() {
 | 
			
		||||
    for (int i = 0; i < wizards.length; i++) {
 | 
			
		||||
@@ -44,7 +44,8 @@ public class VirtualMachine {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Executes provided bytecode
 | 
			
		||||
   * Executes provided bytecode.
 | 
			
		||||
   *
 | 
			
		||||
   * @param bytecode to execute
 | 
			
		||||
   */
 | 
			
		||||
  public void execute(int[] bytecode) {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,8 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class represent game objects which properties can be changed by instructions interpreted by virtual machine
 | 
			
		||||
 * This class represent game objects which properties can be changed by instructions interpreted by
 | 
			
		||||
 * virtual machine.
 | 
			
		||||
 */
 | 
			
		||||
public class Wizard {
 | 
			
		||||
  private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -26,11 +26,11 @@ package com.iluwatar.bytecode.util;
 | 
			
		||||
import com.iluwatar.bytecode.Instruction;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utility class used for instruction validation and conversion
 | 
			
		||||
 * Utility class used for instruction validation and conversion.
 | 
			
		||||
 */
 | 
			
		||||
public class InstructionConverterUtil {
 | 
			
		||||
  /**
 | 
			
		||||
   * Converts instructions represented as String
 | 
			
		||||
   * Converts instructions represented as String.
 | 
			
		||||
   *
 | 
			
		||||
   * @param instructions to convert
 | 
			
		||||
   * @return array of int representing bytecode
 | 
			
		||||
@@ -48,7 +48,8 @@ public class InstructionConverterUtil {
 | 
			
		||||
      } else if (isValidInt(splitedInstructions[i])) {
 | 
			
		||||
        bytecode[i] = Integer.valueOf(splitedInstructions[i]);
 | 
			
		||||
      } else {
 | 
			
		||||
        throw new IllegalArgumentException("Invalid instruction or number: " + splitedInstructions[i]);
 | 
			
		||||
        String errorMessage = "Invalid instruction or number: " + splitedInstructions[i];
 | 
			
		||||
        throw new IllegalArgumentException(errorMessage);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
 | 
			
		||||
 * the resources immediately after their use. The resources retain their identity, are kept in some
 | 
			
		||||
 * fast-access storage, and are re-used to avoid having to acquire them again. There are four main
 | 
			
		||||
@@ -43,8 +42,8 @@ import org.slf4j.LoggerFactory;
 | 
			
		||||
 * should be written back to the backing store (i.e. Database) and help keep both data sources
 | 
			
		||||
 * synchronized/up-to-date. This pattern can improve performance and also helps to maintain
 | 
			
		||||
 * consistency between data held in the cache and the data in the underlying data store.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * In this example, the user account ({@link UserAccount}) entity is used as the underlying
 | 
			
		||||
 *
 | 
			
		||||
 * <p>In this example, the user account ({@link UserAccount}) entity is used as the underlying
 | 
			
		||||
 * application data. The cache itself is implemented as an internal (Java) data structure. It adopts
 | 
			
		||||
 * a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The four
 | 
			
		||||
 * strategies are individually tested. The testing of the cache is restricted towards saving and
 | 
			
		||||
@@ -60,7 +59,6 @@ import org.slf4j.LoggerFactory;
 | 
			
		||||
 * @see CacheStore
 | 
			
		||||
 * @see LruCache
 | 
			
		||||
 * @see CachingPolicy
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class App {
 | 
			
		||||
 | 
			
		||||
@@ -68,15 +66,15 @@ public class App {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Program entry point
 | 
			
		||||
   * Program entry point.
 | 
			
		||||
   *
 | 
			
		||||
   * @param args command line args
 | 
			
		||||
   */
 | 
			
		||||
  public static void main(String[] args) {
 | 
			
		||||
    AppManager.initDb(false); // VirtualDB (instead of MongoDB) was used in running the JUnit tests
 | 
			
		||||
                              // and the App class to avoid Maven compilation errors. Set flag to
 | 
			
		||||
                              // true to run the tests with MongoDB (provided that MongoDB is
 | 
			
		||||
                              // installed and socket connection is open).
 | 
			
		||||
    // and the App class to avoid Maven compilation errors. Set flag to
 | 
			
		||||
    // true to run the tests with MongoDB (provided that MongoDB is
 | 
			
		||||
    // installed and socket connection is open).
 | 
			
		||||
    AppManager.initCacheCapacity(3);
 | 
			
		||||
    App app = new App();
 | 
			
		||||
    app.useReadAndWriteThroughStrategy();
 | 
			
		||||
@@ -86,7 +84,7 @@ public class App {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Read-through and write-through
 | 
			
		||||
   * Read-through and write-through.
 | 
			
		||||
   */
 | 
			
		||||
  public void useReadAndWriteThroughStrategy() {
 | 
			
		||||
    LOGGER.info("# CachingPolicy.THROUGH");
 | 
			
		||||
@@ -101,7 +99,7 @@ public class App {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Read-through and write-around
 | 
			
		||||
   * Read-through and write-around.
 | 
			
		||||
   */
 | 
			
		||||
  public void useReadThroughAndWriteAroundStrategy() {
 | 
			
		||||
    LOGGER.info("# CachingPolicy.AROUND");
 | 
			
		||||
@@ -123,7 +121,7 @@ public class App {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Read-through and write-behind
 | 
			
		||||
   * Read-through and write-behind.
 | 
			
		||||
   */
 | 
			
		||||
  public void useReadThroughAndWriteBehindStrategy() {
 | 
			
		||||
    LOGGER.info("# CachingPolicy.BEHIND");
 | 
			
		||||
@@ -147,7 +145,7 @@ public class App {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Cache-Aside
 | 
			
		||||
   * Cache-Aside.
 | 
			
		||||
   */
 | 
			
		||||
  public void useCacheAsideStategy() {
 | 
			
		||||
    LOGGER.info("# CachingPolicy.ASIDE");
 | 
			
		||||
 
 | 
			
		||||
@@ -26,13 +26,11 @@ package com.iluwatar.caching;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * AppManager helps to bridge the gap in communication between the main class and the application's
 | 
			
		||||
 * back-end. DB connection is initialized through this class. The chosen caching strategy/policy is
 | 
			
		||||
 * also initialized here. Before the cache can be used, the size of the cache has to be set.
 | 
			
		||||
 * Depending on the chosen caching policy, AppManager will call the appropriate function in the
 | 
			
		||||
 * CacheStore class.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public final class AppManager {
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +40,6 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   * Developer/Tester is able to choose whether the application should use MongoDB as its underlying
 | 
			
		||||
   * data storage or a simple Java data structure to (temporarily) store the data/objects during
 | 
			
		||||
   * runtime.
 | 
			
		||||
@@ -60,7 +57,7 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Initialize caching policy
 | 
			
		||||
   * Initialize caching policy.
 | 
			
		||||
   */
 | 
			
		||||
  public static void initCachingPolicy(CachingPolicy policy) {
 | 
			
		||||
    cachingPolicy = policy;
 | 
			
		||||
@@ -75,7 +72,7 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Find user account
 | 
			
		||||
   * Find user account.
 | 
			
		||||
   */
 | 
			
		||||
  public static UserAccount find(String userId) {
 | 
			
		||||
    if (cachingPolicy == CachingPolicy.THROUGH || cachingPolicy == CachingPolicy.AROUND) {
 | 
			
		||||
@@ -89,7 +86,7 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Save user account
 | 
			
		||||
   * Save user account.
 | 
			
		||||
   */
 | 
			
		||||
  public static void save(UserAccount userAccount) {
 | 
			
		||||
    if (cachingPolicy == CachingPolicy.THROUGH) {
 | 
			
		||||
@@ -108,7 +105,7 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Cache-Aside save user account helper
 | 
			
		||||
   * Cache-Aside save user account helper.
 | 
			
		||||
   */
 | 
			
		||||
  private static void saveAside(UserAccount userAccount) {
 | 
			
		||||
    DbManager.updateDb(userAccount);
 | 
			
		||||
@@ -116,7 +113,7 @@ public final class AppManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Cache-Aside find user account helper
 | 
			
		||||
   * Cache-Aside find user account helper.
 | 
			
		||||
   */
 | 
			
		||||
  private static UserAccount findAside(String userId) {
 | 
			
		||||
    UserAccount userAccount = CacheStore.get(userId);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,12 @@
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.caching;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * The caching strategies are implemented in this class.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class CacheStore {
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +40,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Init cache capacity
 | 
			
		||||
   * Init cache capacity.
 | 
			
		||||
   */
 | 
			
		||||
  public static void initCapacity(int capacity) {
 | 
			
		||||
    if (cache == null) {
 | 
			
		||||
@@ -54,7 +51,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get user account using read-through cache
 | 
			
		||||
   * Get user account using read-through cache.
 | 
			
		||||
   */
 | 
			
		||||
  public static UserAccount readThrough(String userId) {
 | 
			
		||||
    if (cache.contains(userId)) {
 | 
			
		||||
@@ -68,7 +65,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get user account using write-through cache
 | 
			
		||||
   * Get user account using write-through cache.
 | 
			
		||||
   */
 | 
			
		||||
  public static void writeThrough(UserAccount userAccount) {
 | 
			
		||||
    if (cache.contains(userAccount.getUserId())) {
 | 
			
		||||
@@ -80,20 +77,20 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get user account using write-around cache
 | 
			
		||||
   * Get user account using write-around cache.
 | 
			
		||||
   */
 | 
			
		||||
  public static void writeAround(UserAccount userAccount) {
 | 
			
		||||
    if (cache.contains(userAccount.getUserId())) {
 | 
			
		||||
      DbManager.updateDb(userAccount);
 | 
			
		||||
      cache.invalidate(userAccount.getUserId()); // Cache data has been updated -- remove older
 | 
			
		||||
                                                 // version from cache.
 | 
			
		||||
      // version from cache.
 | 
			
		||||
    } else {
 | 
			
		||||
      DbManager.writeToDb(userAccount);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get user account using read-through cache with write-back policy
 | 
			
		||||
   * Get user account using read-through cache with write-back policy.
 | 
			
		||||
   */
 | 
			
		||||
  public static UserAccount readThroughWithWriteBackPolicy(String userId) {
 | 
			
		||||
    if (cache.contains(userId)) {
 | 
			
		||||
@@ -112,7 +109,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set user account
 | 
			
		||||
   * Set user account.
 | 
			
		||||
   */
 | 
			
		||||
  public static void writeBehind(UserAccount userAccount) {
 | 
			
		||||
    if (cache.isFull() && !cache.contains(userAccount.getUserId())) {
 | 
			
		||||
@@ -124,7 +121,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Clears cache
 | 
			
		||||
   * Clears cache.
 | 
			
		||||
   */
 | 
			
		||||
  public static void clearCache() {
 | 
			
		||||
    if (cache != null) {
 | 
			
		||||
@@ -147,7 +144,7 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Print user accounts
 | 
			
		||||
   * Print user accounts.
 | 
			
		||||
   */
 | 
			
		||||
  public static String print() {
 | 
			
		||||
    List<UserAccount> listOfUserAccounts = cache.getCacheDataInListForm();
 | 
			
		||||
@@ -161,21 +158,21 @@ public class CacheStore {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delegate to backing cache store
 | 
			
		||||
   * Delegate to backing cache store.
 | 
			
		||||
   */
 | 
			
		||||
  public static UserAccount get(String userId) {
 | 
			
		||||
    return cache.get(userId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delegate to backing cache store
 | 
			
		||||
   * Delegate to backing cache store.
 | 
			
		||||
   */
 | 
			
		||||
  public static void set(String userId, UserAccount userAccount) {
 | 
			
		||||
    cache.set(userId, userAccount);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delegate to backing cache store
 | 
			
		||||
   * Delegate to backing cache store.
 | 
			
		||||
   */
 | 
			
		||||
  public static void invalidate(String userId) {
 | 
			
		||||
    cache.invalidate(userId);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,7 @@
 | 
			
		||||
package com.iluwatar.caching;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Enum class containing the four caching strategies implemented in the pattern.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public enum CachingPolicy {
 | 
			
		||||
  THROUGH("through"), AROUND("around"), BEHIND("behind"), ASIDE("aside");
 | 
			
		||||
 
 | 
			
		||||
@@ -23,28 +23,24 @@
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.caching;
 | 
			
		||||
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.bson.Document;
 | 
			
		||||
 | 
			
		||||
import com.iluwatar.caching.constants.CachingConstants;
 | 
			
		||||
import com.mongodb.MongoClient;
 | 
			
		||||
import com.mongodb.client.FindIterable;
 | 
			
		||||
import com.mongodb.client.MongoDatabase;
 | 
			
		||||
import com.mongodb.client.model.UpdateOptions;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import org.bson.Document;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <p>DBManager handles the communication with the underlying data store i.e. Database. It contains
 | 
			
		||||
 * the implemented methods for querying, inserting, and updating data. MongoDB was used as the
 | 
			
		||||
 * database for the application.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>DBManager handles the communication with the underlying data store i.e. Database. It contains the
 | 
			
		||||
 * implemented methods for querying, inserting, and updating data. MongoDB was used as the database
 | 
			
		||||
 * for the application.</p>
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>Developer/Tester is able to choose whether the application should use MongoDB as its underlying
 | 
			
		||||
 * data storage (connect()) or a simple Java data structure to (temporarily) store the data/objects
 | 
			
		||||
 * during runtime (createVirtualDB()).</p>
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>Developer/Tester is able to choose whether the application should use MongoDB as its
 | 
			
		||||
 * underlying data storage (connect()) or a simple Java data structure to (temporarily) store the
 | 
			
		||||
 * data/objects during runtime (createVirtualDB()).</p>
 | 
			
		||||
 */
 | 
			
		||||
public final class DbManager {
 | 
			
		||||
 | 
			
		||||
@@ -58,7 +54,7 @@ public final class DbManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create DB
 | 
			
		||||
   * Create DB.
 | 
			
		||||
   */
 | 
			
		||||
  public static void createVirtualDb() {
 | 
			
		||||
    useMongoDB = false;
 | 
			
		||||
@@ -66,7 +62,7 @@ public final class DbManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Connect to DB
 | 
			
		||||
   * Connect to DB.
 | 
			
		||||
   */
 | 
			
		||||
  public static void connect() throws ParseException {
 | 
			
		||||
    useMongoDB = true;
 | 
			
		||||
@@ -75,7 +71,7 @@ public final class DbManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Read user account from DB
 | 
			
		||||
   * Read user account from DB.
 | 
			
		||||
   */
 | 
			
		||||
  public static UserAccount readFromDb(String userId) {
 | 
			
		||||
    if (!useMongoDB) {
 | 
			
		||||
@@ -91,17 +87,20 @@ public final class DbManager {
 | 
			
		||||
        e.printStackTrace();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    FindIterable<Document> iterable =
 | 
			
		||||
        db.getCollection(CachingConstants.USER_ACCOUNT).find(new Document(CachingConstants.USER_ID, userId));
 | 
			
		||||
    FindIterable<Document> iterable = db
 | 
			
		||||
        .getCollection(CachingConstants.USER_ACCOUNT)
 | 
			
		||||
        .find(new Document(CachingConstants.USER_ID, userId));
 | 
			
		||||
    if (iterable == null) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    Document doc = iterable.first();
 | 
			
		||||
    return new UserAccount(userId, doc.getString(CachingConstants.USER_NAME), doc.getString(CachingConstants.ADD_INFO));
 | 
			
		||||
    String userName = doc.getString(CachingConstants.USER_NAME);
 | 
			
		||||
    String appInfo = doc.getString(CachingConstants.ADD_INFO);
 | 
			
		||||
    return new UserAccount(userId, userName, appInfo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Write user account to DB
 | 
			
		||||
   * Write user account to DB.
 | 
			
		||||
   */
 | 
			
		||||
  public static void writeToDb(UserAccount userAccount) {
 | 
			
		||||
    if (!useMongoDB) {
 | 
			
		||||
@@ -116,12 +115,14 @@ public final class DbManager {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    db.getCollection(CachingConstants.USER_ACCOUNT).insertOne(
 | 
			
		||||
        new Document(CachingConstants.USER_ID ,userAccount.getUserId()).append(CachingConstants.USER_NAME,
 | 
			
		||||
            userAccount.getUserName()).append(CachingConstants.ADD_INFO, userAccount.getAdditionalInfo()));
 | 
			
		||||
        new Document(CachingConstants.USER_ID, userAccount.getUserId())
 | 
			
		||||
            .append(CachingConstants.USER_NAME, userAccount.getUserName())
 | 
			
		||||
            .append(CachingConstants.ADD_INFO, userAccount.getAdditionalInfo())
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Update DB
 | 
			
		||||
   * Update DB.
 | 
			
		||||
   */
 | 
			
		||||
  public static void updateDb(UserAccount userAccount) {
 | 
			
		||||
    if (!useMongoDB) {
 | 
			
		||||
@@ -142,7 +143,6 @@ public final class DbManager {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   *
 | 
			
		||||
   * Insert data into DB if it does not exist. Else, update it.
 | 
			
		||||
   */
 | 
			
		||||
  public static void upsertDb(UserAccount userAccount) {
 | 
			
		||||
@@ -161,8 +161,10 @@ public final class DbManager {
 | 
			
		||||
        new Document(CachingConstants.USER_ID, userAccount.getUserId()),
 | 
			
		||||
        new Document("$set",
 | 
			
		||||
            new Document(CachingConstants.USER_ID, userAccount.getUserId())
 | 
			
		||||
                .append(CachingConstants.USER_NAME, userAccount.getUserName()).append(CachingConstants.ADD_INFO,
 | 
			
		||||
                    userAccount.getAdditionalInfo())),
 | 
			
		||||
        new UpdateOptions().upsert(true));
 | 
			
		||||
                .append(CachingConstants.USER_NAME, userAccount.getUserName())
 | 
			
		||||
                .append(CachingConstants.ADD_INFO, userAccount.getAdditionalInfo())
 | 
			
		||||
        ),
 | 
			
		||||
        new UpdateOptions().upsert(true)
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,22 +23,19 @@
 | 
			
		||||
 | 
			
		||||
package com.iluwatar.caching;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Data structure/implementation of the application's cache. The data structure consists of a hash
 | 
			
		||||
 * table attached with a doubly linked-list. The linked-list helps in capturing and maintaining the
 | 
			
		||||
 * LRU data in the cache. When a data is queried (from the cache), added (to the cache), or updated,
 | 
			
		||||
 * the data is moved to the front of the list to depict itself as the most-recently-used data. The
 | 
			
		||||
 * LRU data is always at the end of the list.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
public class LruCache {
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +63,7 @@ public class LruCache {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get user account
 | 
			
		||||
   * Get user account.
 | 
			
		||||
   */
 | 
			
		||||
  public UserAccount get(String userId) {
 | 
			
		||||
    if (cache.containsKey(userId)) {
 | 
			
		||||
@@ -110,7 +107,7 @@ public class LruCache {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set user account
 | 
			
		||||
   * Set user account.
 | 
			
		||||
   */
 | 
			
		||||
  public void set(String userId, UserAccount userAccount) {
 | 
			
		||||
    if (cache.containsKey(userId)) {
 | 
			
		||||
@@ -137,7 +134,7 @@ public class LruCache {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Invalidate cache for user
 | 
			
		||||
   * Invalidate cache for user.
 | 
			
		||||
   */
 | 
			
		||||
  public void invalidate(String userId) {
 | 
			
		||||
    Node toBeRemoved = cache.remove(userId);
 | 
			
		||||
@@ -156,7 +153,7 @@ public class LruCache {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Clear cache
 | 
			
		||||
   * Clear cache.
 | 
			
		||||
   */
 | 
			
		||||
  public void clear() {
 | 
			
		||||
    head = null;
 | 
			
		||||
@@ -178,12 +175,12 @@ public class LruCache {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set cache capacity
 | 
			
		||||
   * Set cache capacity.
 | 
			
		||||
   */
 | 
			
		||||
  public void setCapacity(int newCapacity) {
 | 
			
		||||
    if (capacity > newCapacity) {
 | 
			
		||||
      clear(); // Behavior can be modified to accommodate for decrease in cache size. For now, we'll
 | 
			
		||||
               // just clear the cache.
 | 
			
		||||
      // just clear the cache.
 | 
			
		||||
    } else {
 | 
			
		||||
      this.capacity = newCapacity;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ public class UserAccount {
 | 
			
		||||
  private String additionalInfo;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructor
 | 
			
		||||
   * Constructor.
 | 
			
		||||
   */
 | 
			
		||||
  public UserAccount(String userId, String userName, String additionalInfo) {
 | 
			
		||||
    this.userId = userId;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,7 @@
 | 
			
		||||
package com.iluwatar.caching.constants;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * Constant class for defining constants
 | 
			
		||||
 *
 | 
			
		||||
 * Constant class for defining constants.
 | 
			
		||||
 */
 | 
			
		||||
public class CachingConstants {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user