From b92eb5229d846694ff021446d5be9a4bfcf23163 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 10 Nov 2019 23:15:17 +0530 Subject: [PATCH] Resolves checkstyle errors for template-method thread-pool throttling tls tolerant-reader (#1073) * Reduces checkstyle errors in template-method * Reduces checkstyle errors in thread-pool * Reduces checkstyle errors in throttling * Reduces checkstyle errors in tls * Reduces checkstyle errors in tolerant-reader --- .../java/com/iluwatar/templatemethod/App.java | 12 ++- .../templatemethod/HalflingThief.java | 2 - .../templatemethod/HitAndRunMethod.java | 2 - .../templatemethod/StealingMethod.java | 4 +- .../iluwatar/templatemethod/SubtleMethod.java | 2 - .../java/com/iluwatar/threadpool/App.java | 52 +++++------ .../iluwatar/threadpool/CoffeeMakingTask.java | 4 +- .../threadpool/PotatoPeelingTask.java | 4 +- .../java/com/iluwatar/threadpool/Task.java | 4 +- .../java/com/iluwatar/threadpool/Worker.java | 5 +- .../java/com/iluwatar/throttling/App.java | 35 ++++---- .../com/iluwatar/throttling/B2BService.java | 10 +-- .../com/iluwatar/throttling/CallsCount.java | 20 +++-- .../java/com/iluwatar/throttling/Tenant.java | 3 +- .../throttling/timer/ThrottleTimerImpl.java | 8 +- .../iluwatar/throttling/timer/Throttler.java | 5 +- tls/src/main/java/com/iluwatar/tls/App.java | 87 +++++++++---------- .../com/iluwatar/tls/DateFormatCallable.java | 41 ++++----- .../main/java/com/iluwatar/tls/Result.java | 14 +-- .../java/com/iluwatar/tolerantreader/App.java | 25 +++--- .../iluwatar/tolerantreader/RainbowFish.java | 6 +- .../tolerantreader/RainbowFishSerializer.java | 46 +++++----- .../tolerantreader/RainbowFishV2.java | 8 +- 23 files changed, 176 insertions(+), 223 deletions(-) diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/App.java b/template-method/src/main/java/com/iluwatar/templatemethod/App.java index 8776b5ebc..f98e9f760 100644 --- a/template-method/src/main/java/com/iluwatar/templatemethod/App.java +++ b/template-method/src/main/java/com/iluwatar/templatemethod/App.java @@ -24,19 +24,17 @@ package com.iluwatar.templatemethod; /** - * * Template Method defines a skeleton for an algorithm. The algorithm subclasses provide * implementation for the blank parts. - *

- * In this example {@link HalflingThief} contains {@link StealingMethod} that can be changed. First - * the thief hits with {@link HitAndRunMethod} and then with {@link SubtleMethod}. - * + * + *

In this example {@link HalflingThief} contains {@link StealingMethod} that can be changed. + * First the thief hits with {@link HitAndRunMethod} and then with {@link SubtleMethod}. */ public class App { /** - * Program entry point - * + * Program entry point. + * * @param args command line args */ public static void main(String[] args) { diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/HalflingThief.java b/template-method/src/main/java/com/iluwatar/templatemethod/HalflingThief.java index 545c9fbd3..631a58600 100644 --- a/template-method/src/main/java/com/iluwatar/templatemethod/HalflingThief.java +++ b/template-method/src/main/java/com/iluwatar/templatemethod/HalflingThief.java @@ -24,9 +24,7 @@ package com.iluwatar.templatemethod; /** - * * Halfling thief uses {@link StealingMethod} to steal. - * */ public class HalflingThief { diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/HitAndRunMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/HitAndRunMethod.java index bdb6771cd..4ede6f023 100644 --- a/template-method/src/main/java/com/iluwatar/templatemethod/HitAndRunMethod.java +++ b/template-method/src/main/java/com/iluwatar/templatemethod/HitAndRunMethod.java @@ -27,9 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * HitAndRunMethod implementation of {@link StealingMethod}. - * */ public class HitAndRunMethod extends StealingMethod { diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/StealingMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/StealingMethod.java index 6ac898bca..bf206f3a5 100644 --- a/template-method/src/main/java/com/iluwatar/templatemethod/StealingMethod.java +++ b/template-method/src/main/java/com/iluwatar/templatemethod/StealingMethod.java @@ -27,9 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * StealingMethod defines skeleton for the algorithm. - * */ public abstract class StealingMethod { @@ -42,7 +40,7 @@ public abstract class StealingMethod { protected abstract void stealTheItem(String target); /** - * Steal + * Steal. */ public void steal() { var target = pickTarget(); diff --git a/template-method/src/main/java/com/iluwatar/templatemethod/SubtleMethod.java b/template-method/src/main/java/com/iluwatar/templatemethod/SubtleMethod.java index 500769813..eaf897667 100644 --- a/template-method/src/main/java/com/iluwatar/templatemethod/SubtleMethod.java +++ b/template-method/src/main/java/com/iluwatar/templatemethod/SubtleMethod.java @@ -27,9 +27,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * SubtleMethod implementation of {@link StealingMethod}. - * */ public class SubtleMethod extends StealingMethod { diff --git a/thread-pool/src/main/java/com/iluwatar/threadpool/App.java b/thread-pool/src/main/java/com/iluwatar/threadpool/App.java index b21f8cc4a..0d5ee23f5 100644 --- a/thread-pool/src/main/java/com/iluwatar/threadpool/App.java +++ b/thread-pool/src/main/java/com/iluwatar/threadpool/App.java @@ -23,36 +23,32 @@ package com.iluwatar.threadpool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * * Thread Pool pattern is where a number of threads are created to perform a number of tasks, which * are usually organized in a queue. The results from the tasks being executed might also be placed * in a queue, or the tasks might return no result. Typically, there are many more tasks than * threads. As soon as a thread completes its task, it will request the next task from the queue * until all tasks have been completed. The thread can then terminate, or sleep until there are new * tasks available. - *

- * In this example we create a list of tasks presenting work to be done. Each task is then wrapped - * into a {@link Worker} object that implements {@link Runnable}. We create an - * {@link ExecutorService} with fixed number of threads (Thread Pool) and use them to execute the - * {@link Worker}s. * + *

In this example we create a list of tasks presenting work to be done. Each task is then + * wrapped into a {@link Worker} object that implements {@link Runnable}. We create an {@link + * ExecutorService} with fixed number of threads (Thread Pool) and use them to execute the {@link + * Worker}s. */ public class App { - + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** - * Program entry point - * + * Program entry point. + * * @param args command line args */ public static void main(String[] args) { @@ -61,21 +57,21 @@ public class App { // Create a list of tasks to be executed List tasks = List.of( - new PotatoPeelingTask(3), - new PotatoPeelingTask(6), - new CoffeeMakingTask(2), - new CoffeeMakingTask(6), - new PotatoPeelingTask(4), - new CoffeeMakingTask(2), - new PotatoPeelingTask(4), - new CoffeeMakingTask(9), - new PotatoPeelingTask(3), - new CoffeeMakingTask(2), - new PotatoPeelingTask(4), - new CoffeeMakingTask(2), - new CoffeeMakingTask(7), - new PotatoPeelingTask(4), - new PotatoPeelingTask(5)); + new PotatoPeelingTask(3), + new PotatoPeelingTask(6), + new CoffeeMakingTask(2), + new CoffeeMakingTask(6), + new PotatoPeelingTask(4), + new CoffeeMakingTask(2), + new PotatoPeelingTask(4), + new CoffeeMakingTask(9), + new PotatoPeelingTask(3), + new CoffeeMakingTask(2), + new PotatoPeelingTask(4), + new CoffeeMakingTask(2), + new CoffeeMakingTask(7), + new PotatoPeelingTask(4), + new PotatoPeelingTask(5)); // Creates a thread pool that reuses a fixed number of threads operating off a shared // unbounded queue. At any point, at most nThreads threads will be active processing diff --git a/thread-pool/src/main/java/com/iluwatar/threadpool/CoffeeMakingTask.java b/thread-pool/src/main/java/com/iluwatar/threadpool/CoffeeMakingTask.java index 295d898d4..46f5ea254 100644 --- a/thread-pool/src/main/java/com/iluwatar/threadpool/CoffeeMakingTask.java +++ b/thread-pool/src/main/java/com/iluwatar/threadpool/CoffeeMakingTask.java @@ -24,9 +24,7 @@ package com.iluwatar.threadpool; /** - * - * CoffeeMakingTask is a concrete task - * + * CoffeeMakingTask is a concrete task. */ public class CoffeeMakingTask extends Task { diff --git a/thread-pool/src/main/java/com/iluwatar/threadpool/PotatoPeelingTask.java b/thread-pool/src/main/java/com/iluwatar/threadpool/PotatoPeelingTask.java index 19e4025b1..f0e6fd633 100644 --- a/thread-pool/src/main/java/com/iluwatar/threadpool/PotatoPeelingTask.java +++ b/thread-pool/src/main/java/com/iluwatar/threadpool/PotatoPeelingTask.java @@ -24,9 +24,7 @@ package com.iluwatar.threadpool; /** - * - * PotatoPeelingTask is a concrete task - * + * PotatoPeelingTask is a concrete task. */ public class PotatoPeelingTask extends Task { diff --git a/thread-pool/src/main/java/com/iluwatar/threadpool/Task.java b/thread-pool/src/main/java/com/iluwatar/threadpool/Task.java index abf041611..7822f1638 100644 --- a/thread-pool/src/main/java/com/iluwatar/threadpool/Task.java +++ b/thread-pool/src/main/java/com/iluwatar/threadpool/Task.java @@ -26,9 +26,7 @@ package com.iluwatar.threadpool; import java.util.concurrent.atomic.AtomicInteger; /** - * - * Abstract base class for tasks - * + * Abstract base class for tasks. */ public abstract class Task { diff --git a/thread-pool/src/main/java/com/iluwatar/threadpool/Worker.java b/thread-pool/src/main/java/com/iluwatar/threadpool/Worker.java index 6b7f73896..def9e0b22 100644 --- a/thread-pool/src/main/java/com/iluwatar/threadpool/Worker.java +++ b/thread-pool/src/main/java/com/iluwatar/threadpool/Worker.java @@ -27,9 +27,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * - * Worker implements {@link Runnable} and thus can be executed by {@link java.util.concurrent.ExecutorService} - * + * Worker implements {@link Runnable} and thus can be executed by {@link + * java.util.concurrent.ExecutorService}. */ public class Worker implements Runnable { diff --git a/throttling/src/main/java/com/iluwatar/throttling/App.java b/throttling/src/main/java/com/iluwatar/throttling/App.java index 61674eb16..f7b06f652 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/App.java +++ b/throttling/src/main/java/com/iluwatar/throttling/App.java @@ -23,33 +23,30 @@ package com.iluwatar.throttling; +import com.iluwatar.throttling.timer.ThrottleTimerImpl; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.iluwatar.throttling.timer.Throttler; -import com.iluwatar.throttling.timer.ThrottleTimerImpl; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - /** - * Throttling pattern is a design pattern to throttle or limit the use of resources or even a complete service by - * users or a particular tenant. This can allow systems to continue to function and meet service level agreements, - * even when an increase in demand places load on resources. + * Throttling pattern is a design pattern to throttle or limit the use of resources or even a + * complete service by users or a particular tenant. This can allow systems to continue to function + * and meet service level agreements, even when an increase in demand places load on resources. *

- * In this example we have ({@link App}) as the initiating point of the service. - * This is a time based throttling, i.e. only a certain number of calls are allowed per second. + * In this example we have ({@link App}) as the initiating point of the service. This is a time + * based throttling, i.e. only a certain number of calls are allowed per second. *

- * ({@link Tenant}) is the Tenant POJO class with which many tenants can be created - * ({@link B2BService}) is the service which is consumed by the tenants and is throttled. + * ({@link Tenant}) is the Tenant POJO class with which many tenants can be created ({@link + * B2BService}) is the service which is consumed by the tenants and is throttled. */ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** - * Application entry point + * Application entry point. + * * @param args main arguments */ public static void main(String[] args) { @@ -58,10 +55,10 @@ public class App { var nike = new Tenant("Nike", 6, callsCount); var executorService = Executors.newFixedThreadPool(2); - + executorService.execute(() -> makeServiceCalls(adidas, callsCount)); executorService.execute(() -> makeServiceCalls(nike, callsCount)); - + executorService.shutdown(); try { executorService.awaitTermination(10, TimeUnit.SECONDS); @@ -71,14 +68,14 @@ public class App { } /** - * Make calls to the B2BService dummy API + * Make calls to the B2BService dummy API. */ private static void makeServiceCalls(Tenant tenant, CallsCount callsCount) { var timer = new ThrottleTimerImpl(10, callsCount); var service = new B2BService(timer, callsCount); for (int i = 0; i < 20; i++) { service.dummyCustomerApi(tenant); -// Sleep is introduced to keep the output in check and easy to view and analyze the results. + // Sleep is introduced to keep the output in check and easy to view and analyze the results. try { Thread.sleep(1); } catch (InterruptedException e) { diff --git a/throttling/src/main/java/com/iluwatar/throttling/B2BService.java b/throttling/src/main/java/com/iluwatar/throttling/B2BService.java index c00da6a3e..a0e3a571a 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/B2BService.java +++ b/throttling/src/main/java/com/iluwatar/throttling/B2BService.java @@ -23,15 +23,14 @@ package com.iluwatar.throttling; +import com.iluwatar.throttling.timer.Throttler; +import java.util.concurrent.ThreadLocalRandom; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.iluwatar.throttling.timer.Throttler; - -import java.util.concurrent.ThreadLocalRandom; - /** - * A service which accepts a tenant and throttles the resource based on the time given to the tenant. + * A service which accepts a tenant and throttles the resource based on the time given to the + * tenant. */ class B2BService { @@ -44,6 +43,7 @@ class B2BService { } /** + * Calls dummy customer api. * * @return customer id which is randomly generated */ diff --git a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java index 0e24db6a2..a1364ed97 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java +++ b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java @@ -23,18 +23,17 @@ package com.iluwatar.throttling; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * A class to keep track of the counter of different Tenants - * @author drastogi + * A class to keep track of the counter of different Tenants. * + * @author drastogi */ public final class CallsCount { @@ -43,29 +42,32 @@ public final class CallsCount { /** * Add a new tenant to the map. + * * @param tenantName name of the tenant. */ public void addTenant(String tenantName) { tenantCallsCount.putIfAbsent(tenantName, new AtomicLong(0)); } - + /** * Increment the count of the specified tenant. + * * @param tenantName name of the tenant. */ public void incrementCount(String tenantName) { tenantCallsCount.get(tenantName).incrementAndGet(); } - + /** - * + * Get count of tenant based on tenant name. + * * @param tenantName name of the tenant. * @return the count of the tenant. */ public long getCount(String tenantName) { return tenantCallsCount.get(tenantName).get(); } - + /** * Resets the count of all the tenants in the map. */ diff --git a/throttling/src/main/java/com/iluwatar/throttling/Tenant.java b/throttling/src/main/java/com/iluwatar/throttling/Tenant.java index d41674b0e..d94344428 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/Tenant.java +++ b/throttling/src/main/java/com/iluwatar/throttling/Tenant.java @@ -34,8 +34,9 @@ public class Tenant { private int allowedCallsPerSecond; /** + * Constructor. * - * @param name Name of the tenant + * @param name Name of the tenant * @param allowedCallsPerSecond The number of calls allowed for a particular tenant. * @throws InvalidParameterException If number of calls is less than 0, throws exception. */ diff --git a/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java b/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java index c49c142e2..70d3c5074 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java +++ b/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java @@ -21,16 +21,12 @@ * THE SOFTWARE. */ -/** - * - */ package com.iluwatar.throttling.timer; +import com.iluwatar.throttling.CallsCount; import java.util.Timer; import java.util.TimerTask; -import com.iluwatar.throttling.CallsCount; - /** * Implementation of throttler interface. This class resets the counter every second. * @author drastogi @@ -45,7 +41,7 @@ public class ThrottleTimerImpl implements Throttler { this.throttlePeriod = throttlePeriod; this.callsCount = callsCount; } - + /** * A timer is initiated with this method. The timer runs every second and resets the * counter. diff --git a/throttling/src/main/java/com/iluwatar/throttling/timer/Throttler.java b/throttling/src/main/java/com/iluwatar/throttling/timer/Throttler.java index 970fcf32a..2f4fca30e 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/timer/Throttler.java +++ b/throttling/src/main/java/com/iluwatar/throttling/timer/Throttler.java @@ -21,9 +21,6 @@ * THE SOFTWARE. */ -/** - * - */ package com.iluwatar.throttling.timer; /** @@ -32,6 +29,6 @@ package com.iluwatar.throttling.timer; * */ public interface Throttler { - + void start(); } diff --git a/tls/src/main/java/com/iluwatar/tls/App.java b/tls/src/main/java/com/iluwatar/tls/App.java index 026e122f2..35cd89aad 100644 --- a/tls/src/main/java/com/iluwatar/tls/App.java +++ b/tls/src/main/java/com/iluwatar/tls/App.java @@ -23,58 +23,52 @@ package com.iluwatar.tls; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Calendar; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * ThreadLocal pattern - *

- * This App shows how to create an isolated space per each thread. In this - * example the usage of SimpleDateFormat is made to be thread-safe. This is an - * example of the ThreadLocal pattern. - *

- * By applying the ThreadLocal pattern you can keep track of application - * instances or locale settings throughout the handling of a request. The - * ThreadLocal class works like a static variable, with the exception that it is - * only bound to the current thread! This allows us to use static variables in a - * thread-safe way. - *

- * In Java, thread-local variables are implemented by the ThreadLocal class - * object. ThreadLocal holds a variable of type T, which is accessible via get/set - * methods. - *

- * SimpleDateFormat is one of the basic Java classes and is not thread-safe. If - * you do not isolate the instance of SimpleDateFormat per each thread then - * problems arise. - *

- * App converts the String date value 15/12/2015 to the Date format using the - * Java class SimpleDateFormat. It does this 20 times using 4 threads, each doing - * it 5 times. With the usage of as ThreadLocal in DateFormatCallable everything - * runs well. But if you comment out the ThreadLocal variant (marked with "//TLTL") - * and comment in the non ThreadLocal variant (marked with "//NTLNTL") you can - * see what will happen without the ThreadLocal. Most likely you will get incorrect - * date values and / or exceptions. - *

- * This example clearly show what will happen when using non thread-safe classes - * in a thread. In real life this may happen one in of 1.000 or 10.000 conversions - * and those are really hard to find errors. - * - * @author Thomas Bauer, 2017 + * + *

This App shows how to create an isolated space per each thread. In this example the usage of + * SimpleDateFormat is made to be thread-safe. This is an example of the ThreadLocal pattern. + * + *

By applying the ThreadLocal pattern you can keep track of application instances or locale + * settings throughout the handling of a request. The ThreadLocal class works like a static + * variable, with the exception that it is only bound to the current thread! This allows us to use + * static variables in a thread-safe way. + * + *

In Java, thread-local variables are implemented by the ThreadLocal class object. ThreadLocal + * holds a variable of type T, which is accessible via get/set methods. + * + *

SimpleDateFormat is one of the basic Java classes and is not thread-safe. If you do not + * isolate the instance of SimpleDateFormat per each thread then problems arise. + * + *

App converts the String date value 15/12/2015 to the Date format using the Java class + * SimpleDateFormat. It does this 20 times using 4 threads, each doing it 5 times. With the usage of + * as ThreadLocal in DateFormatCallable everything runs well. But if you comment out the ThreadLocal + * variant (marked with "//TLTL") and comment in the non ThreadLocal variant (marked with + * "//NTLNTL") you can see what will happen without the ThreadLocal. Most likely you will get + * incorrect date values and / or exceptions. + * + *

This example clearly show what will happen when using non thread-safe classes in a thread. In + * real life this may happen one in of 1.000 or 10.000 conversions and those are really hard to find + * errors. + * + * @author Thomas Bauer, 2017 */ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + /** - * Program entry point - * - * @param args - * command line args + * Program entry point. + * + * @param args command line args */ public static void main(String[] args) { int counterDateValues = 0; @@ -115,9 +109,9 @@ public class App { } /** - * Print result (date values) of a thread execution and count dates - * - * @param res contains results of a thread execution + * Print result (date values) of a thread execution and count dates. + * + * @param res contains results of a thread execution */ private static int printAndCountDates(Result res) { // a correct run should deliver 5 times 15.12.2015 per each thread @@ -128,15 +122,16 @@ public class App { cal.setTime(dt); // Formatted output of the date value: DD.MM.YYYY LOGGER.info( - cal.get(Calendar.DAY_OF_MONTH) + "." + cal.get(Calendar.MONTH) + "." + +cal.get(Calendar.YEAR)); + cal.get(Calendar.DAY_OF_MONTH) + "." + cal.get(Calendar.MONTH) + "." + +cal + .get(Calendar.YEAR)); } return counter; } /** - * Print result (exceptions) of a thread execution and count exceptions - * - * @param res contains results of a thread execution + * Print result (exceptions) of a thread execution and count exceptions. + * + * @param res contains results of a thread execution * @return number of dates */ private static int printAndCountExceptions(Result res) { diff --git a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java index d83ad6441..8f0006b9e 100644 --- a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java +++ b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java @@ -23,25 +23,23 @@ package com.iluwatar.tls; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.concurrent.Callable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * DateFormatCallable converts string dates to a date format using - * SimpleDateFormat. The date format and the date value will be passed to the - * Callable by the constructor. The constructor creates a instance of - * SimpleDateFormat and stores it in a ThreadLocal class variable. For the - * complete description of the example see {@link App} - * - * You can comment out the code marked with //TLTL and comment in the - * code marked //NTLNTL. Then you can see what will happen if you do not - * use the ThreadLocal. For details see the description of {@link App} + * DateFormatCallable converts string dates to a date format using SimpleDateFormat. The date format + * and the date value will be passed to the Callable by the constructor. The constructor creates a + * instance of SimpleDateFormat and stores it in a ThreadLocal class variable. For the complete + * description of the example see {@link App}. * - * @author Thomas Bauer, 2017 + *

You can comment out the code marked with //TLTL and comment in the code marked //NTLNTL. Then + * you can see what will happen if you do not use the ThreadLocal. For details see the description + * of {@link App} + * + * @author Thomas Bauer, 2017 */ public class DateFormatCallable implements Callable { @@ -51,15 +49,13 @@ public class DateFormatCallable implements Callable { // private DateFormat df; //NTLNTL private String dateValue; // for dateValue Thread Local not needed - + /** - * The date format and the date value are passed to the constructor - * - * @param inDateFormat - * string date format string, e.g. "dd/MM/yyyy" - * @param inDateValue - * string date value, e.g. "21/06/2016" + * The date format and the date value are passed to the constructor. + * + * @param inDateFormat string date format string, e.g. "dd/MM/yyyy" + * @param inDateValue string date value, e.g. "21/06/2016" */ public DateFormatCallable(String inDateFormat, String inDateValue) { final String idf = inDateFormat; //TLTL @@ -73,9 +69,6 @@ public class DateFormatCallable implements Callable { this.dateValue = inDateValue; } - /** - * @see java.util.concurrent.Callable#call() - */ @Override public Result call() { LOGGER.info(Thread.currentThread() + " started executing..."); @@ -88,7 +81,7 @@ public class DateFormatCallable implements Callable { // instance of SimpleDateFormat locally // Create the date value and store it in dateList result.getDateList().add(this.df.get().parse(this.dateValue)); //TLTL -// result.getDateList().add(this.df.parse(this.dateValue)); //NTLNTL + // result.getDateList().add(this.df.parse(this.dateValue)); //NTLNTL } catch (Exception e) { // write the Exception to a list and continue work result.getExceptionList().add(e.getClass() + ": " + e.getMessage()); diff --git a/tls/src/main/java/com/iluwatar/tls/Result.java b/tls/src/main/java/com/iluwatar/tls/Result.java index 8e29b0e4a..2dd249c4d 100644 --- a/tls/src/main/java/com/iluwatar/tls/Result.java +++ b/tls/src/main/java/com/iluwatar/tls/Result.java @@ -32,10 +32,10 @@ import java.util.Date; import java.util.List; /** - * Result object that will be returned by the Callable {@link DateFormatCallable} - * used in {@link App} + * Result object that will be returned by the Callable {@link DateFormatCallable} used in {@link + * App}. * - * @author Thomas Bauer, 2017 + * @author Thomas Bauer, 2017 */ public class Result { // A list to collect the date values created in one thread @@ -44,9 +44,10 @@ public class Result { // A list to collect Exceptions thrown in one threads (should be none in // this example) private List exceptionList = new ArrayList(); - + /** - * + * Get list of date values collected within a thread execution. + * * @return List of date values collected within an thread execution */ public List getDateList() { @@ -54,7 +55,8 @@ public class Result { } /** - * + * Get list of exceptions thrown within a thread execution. + * * @return List of exceptions thrown within an thread execution */ public List getExceptionList() { diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/App.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/App.java index 37ab2c2af..c547388a2 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/App.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/App.java @@ -23,32 +23,29 @@ package com.iluwatar.tolerantreader; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; - /** - * * Tolerant Reader is an integration pattern that helps creating robust communication systems. The * idea is to be as tolerant as possible when reading data from another service. This way, when the * communication schema changes, the readers must not break. - *

- * In this example we use Java serialization to write representations of {@link RainbowFish} objects - * to file. {@link RainbowFish} is the initial version which we can easily read and write using - * {@link RainbowFishSerializer} methods. {@link RainbowFish} then evolves to {@link RainbowFishV2} - * and we again write it to file with a method designed to do just that. However, the reader client - * does not know about the new format and still reads with the method designed for V1 schema. - * Fortunately the reading method has been designed with the Tolerant Reader pattern and does not - * break even though {@link RainbowFishV2} has new fields that are serialized. * + *

In this example we use Java serialization to write representations of {@link RainbowFish} + * objects to file. {@link RainbowFish} is the initial version which we can easily read and write + * using {@link RainbowFishSerializer} methods. {@link RainbowFish} then evolves to {@link + * RainbowFishV2} and we again write it to file with a method designed to do just that. However, the + * reader client does not know about the new format and still reads with the method designed for V1 + * schema. Fortunately the reading method has been designed with the Tolerant Reader pattern and + * does not break even though {@link RainbowFishV2} has new fields that are serialized. */ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** - * Program entry point + * Program entry point. */ public static void main(String[] args) throws IOException, ClassNotFoundException { // Write V1 @@ -59,8 +56,8 @@ public class App { // Read V1 var deserializedRainbowFishV1 = RainbowFishSerializer.readV1("fish1.out"); LOGGER.info("deserializedFishV1 name={} age={} length={} weight={}", - deserializedRainbowFishV1.getName(), deserializedRainbowFishV1.getAge(), - deserializedRainbowFishV1.getLengthMeters(), deserializedRainbowFishV1.getWeightTons()); + deserializedRainbowFishV1.getName(), deserializedRainbowFishV1.getAge(), + deserializedRainbowFishV1.getLengthMeters(), deserializedRainbowFishV1.getWeightTons()); // Write V2 var fishV2 = new RainbowFishV2("Scar", 5, 12, 15, true, true, true); LOGGER.info( diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java index 221f1c32f..775fc98f7 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java @@ -26,9 +26,7 @@ package com.iluwatar.tolerantreader; import java.io.Serializable; /** - * - * RainbowFish is the initial schema - * + * RainbowFish is the initial schema. */ public class RainbowFish implements Serializable { @@ -40,7 +38,7 @@ public class RainbowFish implements Serializable { private int weightTons; /** - * Constructor + * Constructor. */ public RainbowFish(String name, int age, int lengthMeters, int weightTons) { this.name = name; diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java index 3e8db7622..33c464190 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java @@ -28,16 +28,13 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.HashMap; import java.util.Map; /** - * * RainbowFishSerializer provides methods for reading and writing {@link RainbowFish} objects to - * file. Tolerant Reader pattern is implemented here by serializing maps instead of - * {@link RainbowFish} objects. This way the reader does not break even though new properties are - * added to the schema. - * + * file. Tolerant Reader pattern is implemented here by serializing maps instead of {@link + * RainbowFish} objects. This way the reader does not break even though new properties are added to + * the schema. */ public final class RainbowFishSerializer { @@ -45,54 +42,55 @@ public final class RainbowFishSerializer { } /** - * Write V1 RainbowFish to file + * Write V1 RainbowFish to file. */ public static void writeV1(RainbowFish rainbowFish, String filename) throws IOException { var map = Map.of( - "name", rainbowFish.getName(), - "age", String.format("%d", rainbowFish.getAge()), - "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), - "weightTons", String.format("%d", rainbowFish.getWeightTons()) + "name", rainbowFish.getName(), + "age", String.format("%d", rainbowFish.getAge()), + "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), + "weightTons", String.format("%d", rainbowFish.getWeightTons()) ); try (var fileOut = new FileOutputStream(filename); - var objOut = new ObjectOutputStream(fileOut)) { + var objOut = new ObjectOutputStream(fileOut)) { objOut.writeObject(map); } } /** - * Write V2 RainbowFish to file + * Write V2 RainbowFish to file. */ public static void writeV2(RainbowFishV2 rainbowFish, String filename) throws IOException { var map = Map.of( - "name", rainbowFish.getName(), - "age", String.format("%d", rainbowFish.getAge()), - "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), - "weightTons", String.format("%d", rainbowFish.getWeightTons()), - "angry", Boolean.toString(rainbowFish.getAngry()), - "hungry", Boolean.toString(rainbowFish.getHungry()), - "sleeping", Boolean.toString(rainbowFish.getSleeping()) + "name", rainbowFish.getName(), + "age", String.format("%d", rainbowFish.getAge()), + "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), + "weightTons", String.format("%d", rainbowFish.getWeightTons()), + "angry", Boolean.toString(rainbowFish.getAngry()), + "hungry", Boolean.toString(rainbowFish.getHungry()), + "sleeping", Boolean.toString(rainbowFish.getSleeping()) ); try (var fileOut = new FileOutputStream(filename); - var objOut = new ObjectOutputStream(fileOut)) { + var objOut = new ObjectOutputStream(fileOut)) { objOut.writeObject(map); } } /** - * Read V1 RainbowFish from file + * Read V1 RainbowFish from file. */ public static RainbowFish readV1(String filename) throws IOException, ClassNotFoundException { Map map = null; try (var fileIn = new FileInputStream(filename); - var objIn = new ObjectInputStream(fileIn)) { + var objIn = new ObjectInputStream(fileIn)) { map = (Map) objIn.readObject(); } - return new RainbowFish(map.get("name"), Integer.parseInt(map.get("age")), Integer.parseInt(map.get("lengthMeters")), + return new RainbowFish(map.get("name"), Integer.parseInt(map.get("age")), Integer + .parseInt(map.get("lengthMeters")), Integer.parseInt(map.get("weightTons"))); } } diff --git a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishV2.java b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishV2.java index a8a551865..3e019097e 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishV2.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishV2.java @@ -24,9 +24,7 @@ package com.iluwatar.tolerantreader; /** - * - * RainbowFishV2 is the evolved schema - * + * RainbowFishV2 is the evolved schema. */ public class RainbowFishV2 extends RainbowFish { @@ -41,10 +39,10 @@ public class RainbowFishV2 extends RainbowFish { } /** - * Constructor + * Constructor. */ public RainbowFishV2(String name, int age, int lengthMeters, int weightTons, boolean sleeping, - boolean hungry, boolean angry) { + boolean hungry, boolean angry) { this(name, age, lengthMeters, weightTons); this.sleeping = sleeping; this.hungry = hungry;