From e6c74a5fb97f3c1faacda5653894eb654be72435 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 21:11:48 +0000 Subject: [PATCH 001/285] Java 11 migraiton: marker --- marker/src/main/java/App.java | 23 ++++------------------- marker/src/main/java/Guard.java | 3 +-- marker/src/main/java/Thief.java | 2 +- marker/src/test/java/AppTest.java | 3 +-- marker/src/test/java/GuardTest.java | 2 +- marker/src/test/java/ThiefTest.java | 10 ++++++---- 6 files changed, 14 insertions(+), 29 deletions(-) diff --git a/marker/src/main/java/App.java b/marker/src/main/java/App.java index 384c999dc..c7b4530c6 100644 --- a/marker/src/main/java/App.java +++ b/marker/src/main/java/App.java @@ -21,9 +21,6 @@ * THE SOFTWARE. */ -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * Created by Alexis on 28-Apr-17. With Marker interface idea is to make empty interface and extend * it. Basically it is just to identify the special objects from normal objects. Like in case of @@ -46,22 +43,10 @@ public class App { * @param args command line args */ public static void main(String[] args) { - - final Logger logger = LoggerFactory.getLogger(App.class); - Guard guard = new Guard(); - Thief thief = new Thief(); - - if (guard instanceof Permission) { - guard.enter(); - } else { - logger.info("You have no permission to enter, please leave this area"); - } - - if (thief instanceof Permission) { - thief.steal(); - } else { - thief.doNothing(); - } + var guard = new Guard(); + var thief = new Thief(); + guard.enter(); + thief.doNothing(); } } diff --git a/marker/src/main/java/Guard.java b/marker/src/main/java/Guard.java index 9a57e15fd..54443603c 100644 --- a/marker/src/main/java/Guard.java +++ b/marker/src/main/java/Guard.java @@ -31,8 +31,7 @@ public class Guard implements Permission { private static final Logger LOGGER = LoggerFactory.getLogger(Guard.class); - protected static void enter() { - + protected void enter() { LOGGER.info("You can enter"); } } diff --git a/marker/src/main/java/Thief.java b/marker/src/main/java/Thief.java index 341eae377..22155ef7b 100644 --- a/marker/src/main/java/Thief.java +++ b/marker/src/main/java/Thief.java @@ -35,7 +35,7 @@ public class Thief { LOGGER.info("Steal valuable items"); } - protected static void doNothing() { + protected void doNothing() { LOGGER.info("Pretend nothing happened and just leave"); } } diff --git a/marker/src/test/java/AppTest.java b/marker/src/test/java/AppTest.java index 5d63db0ad..13295a9e5 100644 --- a/marker/src/test/java/AppTest.java +++ b/marker/src/test/java/AppTest.java @@ -30,7 +30,6 @@ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/marker/src/test/java/GuardTest.java b/marker/src/test/java/GuardTest.java index 615d4e129..ae92c27dc 100644 --- a/marker/src/test/java/GuardTest.java +++ b/marker/src/test/java/GuardTest.java @@ -33,7 +33,7 @@ public class GuardTest { @Test public void testGuard() { - Guard guard = new Guard(); + var guard = new Guard(); assertThat(guard, instanceOf(Permission.class)); } } \ No newline at end of file diff --git a/marker/src/test/java/ThiefTest.java b/marker/src/test/java/ThiefTest.java index 2732fc78a..dc081acf8 100644 --- a/marker/src/test/java/ThiefTest.java +++ b/marker/src/test/java/ThiefTest.java @@ -21,9 +21,11 @@ * THE SOFTWARE. */ -import org.junit.jupiter.api.Test; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; /** * Thief test @@ -31,7 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; public class ThiefTest { @Test public void testThief() { - Thief thief = new Thief(); - assertFalse(thief instanceof Permission); + var thief = new Thief(); + assertThat(thief, not(instanceOf(Permission.class))); } } \ No newline at end of file From 59e050b20b0da4535c3f157c47f5810c2e0f513e Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 21:36:04 +0000 Subject: [PATCH 002/285] Java 11 migraiton: master-worker-pattern --- master-worker-pattern/pom.xml | 67 ++++++++++--------- .../java/com/iluwatar/masterworker/App.java | 50 +++++++------- .../com/iluwatar/masterworker/ArrayInput.java | 29 ++++---- .../masterworker/ArrayUtilityMethods.java | 20 +++--- .../java/com/iluwatar/masterworker/Input.java | 4 +- .../masterworker/system/MasterWorker.java | 2 +- .../systemmaster/ArrayTransposeMaster.java | 43 ++++++------ .../system/systemmaster/Master.java | 33 ++++----- .../systemworkers/ArrayTransposeWorker.java | 12 ++-- .../system/systemworkers/Worker.java | 12 ++-- .../iluwatar/masterworker/ArrayInputTest.java | 41 ++++++------ .../masterworker/ArrayUtilityMethodsTest.java | 14 ++-- .../ArrayTransposeMasterWorkerTest.java | 35 +++++++--- .../ArrayTransposeWorkerTest.java | 26 +++---- 14 files changed, 200 insertions(+), 188 deletions(-) diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index 9924d6a5a..26f4d70bb 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -22,38 +22,39 @@ THE SOFTWARE. --> - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.23.0-SNAPSHOT - - master-worker-pattern - - - org.junit.jupiter - junit-jupiter-engine - test - + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.23.0-SNAPSHOT + + master-worker-pattern + + + org.junit.jupiter + junit-jupiter-engine + test + - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.masterworker.App - - - - - - - - + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.masterworker.App + + + + + + + + diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/App.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/App.java index 547636066..592ba8c59 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/App.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/App.java @@ -34,27 +34,25 @@ import org.slf4j.LoggerFactory; /** *

The Master-Worker pattern is used when the problem at hand can be solved by - * dividing into - * multiple parts which need to go through the same computation and may need to be aggregated to get - * final result. Parallel processing is performed using a system consisting of a master and some - * number of workers, where a master divides the work among the workers, gets the result back from - * them and assimilates all the results to give final result. The only communication is between the - * master and the worker - none of the workers communicate among one another and the user only - * communicates with the master to get required job done.

+ * dividing into multiple parts which need to go through the same computation and may need to be + * aggregated to get final result. Parallel processing is performed using a system consisting of a + * master and some number of workers, where a master divides the work among the workers, gets the + * result back from them and assimilates all the results to give final result. The only + * communication is between the master and the worker - none of the workers communicate among one + * another and the user only communicates with the master to get required job done.

*

In our example, we have generic abstract classes {@link MasterWorker}, {@link Master} and - * {@link Worker} which - * have to be extended by the classes which will perform the specific job at hand (in this case - * finding transpose of matrix, done by {@link ArrayTransposeMasterWorker}, {@link - * ArrayTransposeMaster} and {@link ArrayTransposeWorker}). The Master class divides the work into - * parts to be given to the workers, collects the results from the workers and aggregates it when - * all workers have responded before returning the solution. The Worker class extends the Thread - * class to enable parallel processing, and does the work once the data has been received from the - * Master. The MasterWorker contains a reference to the Master class, gets the input from the App - * and passes it on to the Master. These 3 classes define the system which computes the result. We - * also have 2 abstract classes {@link Input} and {@link Result}, which contain the input data and - * result data respectively. The Input class also has an abstract method divideData which defines - * how the data is to be divided into segments. These classes are extended by {@link ArrayInput} and - * {@link ArrayResult}.

+ * {@link Worker} which have to be extended by the classes which will perform the specific job at + * hand (in this case finding transpose of matrix, done by {@link ArrayTransposeMasterWorker}, + * {@link ArrayTransposeMaster} and {@link ArrayTransposeWorker}). The Master class divides the work + * into parts to be given to the workers, collects the results from the workers and aggregates it + * when all workers have responded before returning the solution. The Worker class extends the + * Thread class to enable parallel processing, and does the work once the data has been received + * from the Master. The MasterWorker contains a reference to the Master class, gets the input from + * the App and passes it on to the Master. These 3 classes define the system which computes the + * result. We also have 2 abstract classes {@link Input} and {@link Result}, which contain the input + * data and result data respectively. The Input class also has an abstract method divideData which + * defines how the data is to be divided into segments. These classes are extended by {@link + * ArrayInput} and {@link ArrayResult}.

*/ public class App { @@ -68,12 +66,12 @@ public class App { */ public static void main(String[] args) { - ArrayTransposeMasterWorker mw = new ArrayTransposeMasterWorker(); - int rows = 10; - int columns = 20; - int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows, columns); - ArrayInput input = new ArrayInput(inputMatrix); - ArrayResult result = (ArrayResult) mw.getResult(input); + var mw = new ArrayTransposeMasterWorker(); + var rows = 10; + var columns = 20; + var inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows, columns); + var input = new ArrayInput(inputMatrix); + var result = (ArrayResult) mw.getResult(input); if (result != null) { ArrayUtilityMethods.printMatrix(inputMatrix); ArrayUtilityMethods.printMatrix(result.data); diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayInput.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayInput.java index cd03a0a21..c8e68f958 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayInput.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayInput.java @@ -25,6 +25,7 @@ package com.iluwatar.masterworker; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * Class ArrayInput extends abstract class {@link Input} and contains data of type int[][]. @@ -37,12 +38,12 @@ public class ArrayInput extends Input { } static int[] makeDivisions(int[][] data, int num) { - int initialDivision = data.length / num; //equally dividing - int[] divisions = new int[num]; + var initialDivision = data.length / num; //equally dividing + var divisions = new int[num]; Arrays.fill(divisions, initialDivision); if (initialDivision * num != data.length) { - int extra = data.length - initialDivision * num; - int l = 0; + var extra = data.length - initialDivision * num; + var l = 0; //equally dividing extra among all parts while (extra > 0) { divisions[l] = divisions[l] + 1; @@ -58,22 +59,20 @@ public class ArrayInput extends Input { } @Override - public ArrayList divideData(int num) { + public List> divideData(int num) { if (this.data == null) { return null; } else { - int[] divisions = makeDivisions(this.data, num); - ArrayList result = new ArrayList(num); - int rowsDone = 0; //number of rows divided so far - for (int i = 0; i < num; i++) { - int rows = divisions[i]; + var divisions = makeDivisions(this.data, num); + var result = new ArrayList>(num); + var rowsDone = 0; //number of rows divided so far + for (var i = 0; i < num; i++) { + var rows = divisions[i]; if (rows != 0) { - int[][] divided = new int[rows][this.data[0].length]; - for (int j = 0; j < rows; j++) { - divided[j] = this.data[rowsDone + j]; - } + var divided = new int[rows][this.data[0].length]; + System.arraycopy(this.data, rowsDone, divided, 0, rows); rowsDone += rows; - ArrayInput dividedInput = new ArrayInput(divided); + var dividedInput = new ArrayInput(divided); result.add(dividedInput); } else { break; //rest of divisions will also be 0 diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayUtilityMethods.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayUtilityMethods.java index 525bed003..5e695e5da 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayUtilityMethods.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/ArrayUtilityMethods.java @@ -47,8 +47,8 @@ public class ArrayUtilityMethods { if (a1.length != a2.length) { return false; } else { - boolean answer = false; - for (int i = 0; i < a1.length; i++) { + var answer = false; + for (var i = 0; i < a1.length; i++) { if (a1[i] == a2[i]) { answer = true; } else { @@ -69,8 +69,8 @@ public class ArrayUtilityMethods { if (m1.length != m2.length) { return false; } else { - boolean answer = false; - for (int i = 0; i < m1.length; i++) { + var answer = false; + for (var i = 0; i < m1.length; i++) { if (arraysSame(m1[i], m2[i])) { answer = true; } else { @@ -88,9 +88,9 @@ public class ArrayUtilityMethods { * @return it (int[][]). */ public static int[][] createRandomIntMatrix(int rows, int columns) { - int[][] matrix = new int[rows][columns]; - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { + var matrix = new int[rows][columns]; + for (var i = 0; i < rows; i++) { + for (var j = 0; j < columns; j++) { //filling cells in matrix matrix[i][j] = RANDOM.nextInt(10); } @@ -104,9 +104,9 @@ public class ArrayUtilityMethods { public static void printMatrix(int[][] matrix) { //prints out int[][] - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - LOGGER.info(matrix[i][j] + " "); + for (var ints : matrix) { + for (var j = 0; j < matrix[0].length; j++) { + LOGGER.info(ints[j] + " "); } LOGGER.info(""); } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/Input.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/Input.java index 6a957ae80..8d832f6c7 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/Input.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/Input.java @@ -23,7 +23,7 @@ package com.iluwatar.masterworker; -import java.util.ArrayList; +import java.util.List; /** * The abstract Input class, having 1 public field which contains input data, and abstract method @@ -40,5 +40,5 @@ public abstract class Input { this.data = data; } - public abstract ArrayList divideData(int num); + public abstract List> divideData(int num); } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/MasterWorker.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/MasterWorker.java index 2b16cbf76..817fd65d3 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/MasterWorker.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/MasterWorker.java @@ -40,7 +40,7 @@ public abstract class MasterWorker { abstract Master setMaster(int numOfWorkers); - public Result getResult(Input input) { + public Result getResult(Input input) { this.master.doWork(input); return this.master.getFinalResult(); } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/ArrayTransposeMaster.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/ArrayTransposeMaster.java index ffa64572c..9bfbf200e 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/ArrayTransposeMaster.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/ArrayTransposeMaster.java @@ -27,7 +27,8 @@ import com.iluwatar.masterworker.ArrayResult; import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker; import com.iluwatar.masterworker.system.systemworkers.Worker; import java.util.ArrayList; -import java.util.Enumeration; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * Class ArrayTransposeMaster extends abstract class {@link Master} and contains definition of @@ -41,35 +42,33 @@ public class ArrayTransposeMaster extends Master { @Override ArrayList setWorkers(int num) { - ArrayList ws = new ArrayList(num); - for (int i = 0; i < num; i++) { - ws.add(new ArrayTransposeWorker(this, i + 1)); - //i+1 will be id - } - return ws; + //i+1 will be id + return IntStream.range(0, num) + .mapToObj(i -> new ArrayTransposeWorker(this, i + 1)) + .collect(Collectors.toCollection(() -> new ArrayList<>(num))); } @Override ArrayResult aggregateData() { // number of rows in final result is number of rows in any of obtained results from workers - int rows = ((ArrayResult) this.getAllResultData() - .get(this.getAllResultData().keys().nextElement())).data.length; - int columns = - 0; //number of columns is sum of number of columns in all results obtained from workers - for (Enumeration e = this.getAllResultData().keys(); e.hasMoreElements(); ) { - columns += ((ArrayResult) this.getAllResultData().get(e.nextElement())).data[0].length; + var allResultData = this.getAllResultData(); + var rows = ((ArrayResult) allResultData.elements().nextElement()).data.length; + var elements = allResultData.elements(); + var columns = 0; // columns = sum of number of columns in all results obtained from workers + while (elements.hasMoreElements()) { + columns += ((ArrayResult) elements.nextElement()).data[0].length; } - int[][] resultData = new int[rows][columns]; - int columnsDone = 0; //columns aggregated so far - for (int i = 0; i < this.getExpectedNumResults(); i++) { + var resultData = new int[rows][columns]; + var columnsDone = 0; //columns aggregated so far + var workers = this.getWorkers(); + for (var i = 0; i < this.getExpectedNumResults(); i++) { //result obtained from ith worker - int[][] work = - ((ArrayResult) this.getAllResultData().get(this.getWorkers().get(i).getWorkerId())).data; - for (int m = 0; m < work.length; m++) { + var worker = workers.get(i); + var workerId = worker.getWorkerId(); + var work = ((ArrayResult) allResultData.get(workerId)).data; + for (var m = 0; m < work.length; m++) { //m = row number, n = columns number - for (int n = 0; n < work[0].length; n++) { - resultData[m][columnsDone + n] = work[m][n]; - } + System.arraycopy(work[m], 0, resultData[m], columnsDone, work[0].length); } columnsDone += work[0].length; } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java index 2466df256..6b20211f5 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java @@ -26,8 +26,9 @@ package com.iluwatar.masterworker.system.systemmaster; import com.iluwatar.masterworker.Input; import com.iluwatar.masterworker.Result; import com.iluwatar.masterworker.system.systemworkers.Worker; -import java.util.ArrayList; +import java.util.Dictionary; import java.util.Hashtable; +import java.util.List; /** * The abstract Master class which contains private fields numOfWorkers (number of workers), workers @@ -38,24 +39,24 @@ import java.util.Hashtable; public abstract class Master { private final int numOfWorkers; - private final ArrayList workers; + private final List workers; + private final Dictionary> allResultData; private int expectedNumResults; - private Hashtable allResultData; - private Result finalResult; + private Result finalResult; Master(int numOfWorkers) { this.numOfWorkers = numOfWorkers; this.workers = setWorkers(numOfWorkers); this.expectedNumResults = 0; - this.allResultData = new Hashtable(numOfWorkers); + this.allResultData = new Hashtable<>(numOfWorkers); this.finalResult = null; } - public Result getFinalResult() { + public Result getFinalResult() { return this.finalResult; } - Hashtable getAllResultData() { + Dictionary> getAllResultData() { return this.allResultData; } @@ -63,21 +64,21 @@ public abstract class Master { return this.expectedNumResults; } - ArrayList getWorkers() { + List getWorkers() { return this.workers; } - abstract ArrayList setWorkers(int num); + abstract List setWorkers(int num); - public void doWork(Input input) { + public void doWork(Input input) { divideWork(input); } - private void divideWork(Input input) { - ArrayList dividedInput = input.divideData(numOfWorkers); + private void divideWork(Input input) { + List> dividedInput = input.divideData(numOfWorkers); if (dividedInput != null) { this.expectedNumResults = dividedInput.size(); - for (int i = 0; i < this.expectedNumResults; i++) { + for (var i = 0; i < this.expectedNumResults; i++) { //ith division given to ith worker in this.workers this.workers.get(i).setReceivedData(this, dividedInput.get(i)); this.workers.get(i).run(); @@ -85,12 +86,12 @@ public abstract class Master { } } - public void receiveData(Result data, Worker w) { + public void receiveData(Result data, Worker w) { //check if can receive..if yes: collectResult(data, w.getWorkerId()); } - private void collectResult(Result data, int workerId) { + private void collectResult(Result data, int workerId) { this.allResultData.put(workerId, data); if (this.allResultData.size() == this.expectedNumResults) { //all data received @@ -98,5 +99,5 @@ public abstract class Master { } } - abstract Result aggregateData(); + abstract Result aggregateData(); } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorker.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorker.java index 37d8ba005..3f2da0a0a 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorker.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorker.java @@ -41,12 +41,12 @@ public class ArrayTransposeWorker extends Worker { @Override ArrayResult executeOperation() { //number of rows in result matrix is equal to number of columns in input matrix and vice versa - ArrayInput arrayInput = (ArrayInput) this.getReceivedData(); - final int rows = arrayInput.data[0].length; - final int cols = arrayInput.data.length; - int[][] resultData = new int[rows][cols]; - for (int i = 0; i < cols; i++) { - for (int j = 0; j < rows; j++) { + var arrayInput = (ArrayInput) this.getReceivedData(); + final var rows = arrayInput.data[0].length; + final var cols = arrayInput.data.length; + var resultData = new int[rows][cols]; + for (var i = 0; i < cols; i++) { + for (var j = 0; j < rows; j++) { //flipping element positions along diagonal resultData[j][i] = arrayInput.data[i][j]; } diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/Worker.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/Worker.java index bfe226ee0..526299645 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/Worker.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemworkers/Worker.java @@ -35,7 +35,7 @@ import com.iluwatar.masterworker.system.systemmaster.Master; public abstract class Worker extends Thread { private final Master master; private final int workerId; - private Input receivedData; + private Input receivedData; Worker(Master master, int id) { this.master = master; @@ -47,23 +47,23 @@ public abstract class Worker extends Thread { return this.workerId; } - Input getReceivedData() { + Input getReceivedData() { return this.receivedData; } - public void setReceivedData(Master m, Input i) { + public void setReceivedData(Master m, Input i) { //check if ready to receive..if yes: this.receivedData = i; } - abstract Result executeOperation(); + abstract Result executeOperation(); - private void sendToMaster(Result data) { + private void sendToMaster(Result data) { this.master.receiveData(data, this); } public void run() { //from Thread class - Result work = executeOperation(); + var work = executeOperation(); sendToMaster(work); } } diff --git a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayInputTest.java b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayInputTest.java index b5820e2af..1d3c7f0bc 100644 --- a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayInputTest.java +++ b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayInputTest.java @@ -23,38 +23,39 @@ package com.iluwatar.masterworker; -import static org.junit.jupiter.api.Assertions.*; -import java.util.ArrayList; +import static com.iluwatar.masterworker.ArrayUtilityMethods.matricesSame; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.Random; import org.junit.jupiter.api.Test; /** -* Testing divideData method in {@link ArrayInput} class. -*/ + * Testing divideData method in {@link ArrayInput} class. + */ class ArrayInputTest { @Test void divideDataTest() { - int rows = 10; - int columns = 10; - int[][] inputMatrix = new int[rows][columns]; - Random rand = new Random(); - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { + var rows = 10; + var columns = 10; + var inputMatrix = new int[rows][columns]; + var rand = new Random(); + for (var i = 0; i < rows; i++) { + for (var j = 0; j < columns; j++) { inputMatrix[i][j] = rand.nextInt(10); } } - ArrayInput i = new ArrayInput(inputMatrix); - ArrayList table = i.divideData(4); - int[][] division1 = new int[][] {inputMatrix[0], inputMatrix[1], inputMatrix[2]}; - int[][] division2 = new int[][] {inputMatrix[3], inputMatrix[4], inputMatrix[5]}; - int[][] division3 = new int[][] {inputMatrix[6], inputMatrix[7]}; - int[][] division4 = new int[][] {inputMatrix[8], inputMatrix[9]}; - assertTrue(ArrayUtilityMethods.matricesSame((int[][]) table.get(0).data, division1) - && ArrayUtilityMethods.matricesSame((int[][]) table.get(1).data, division2) - && ArrayUtilityMethods.matricesSame((int[][]) table.get(2).data, division3) - && ArrayUtilityMethods.matricesSame((int[][]) table.get(3).data, division4)); + var i = new ArrayInput(inputMatrix); + var table = i.divideData(4); + var division1 = new int[][]{inputMatrix[0], inputMatrix[1], inputMatrix[2]}; + var division2 = new int[][]{inputMatrix[3], inputMatrix[4], inputMatrix[5]}; + var division3 = new int[][]{inputMatrix[6], inputMatrix[7]}; + var division4 = new int[][]{inputMatrix[8], inputMatrix[9]}; + assertTrue(matricesSame(table.get(0).data, division1) + && matricesSame(table.get(1).data, division2) + && matricesSame(table.get(2).data, division3) + && matricesSame(table.get(3).data, division4)); } } diff --git a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayUtilityMethodsTest.java b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayUtilityMethodsTest.java index aae784b52..d25276572 100644 --- a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayUtilityMethodsTest.java +++ b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/ArrayUtilityMethodsTest.java @@ -23,27 +23,27 @@ package com.iluwatar.masterworker; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; /** -* Testing utility methods in {@link ArrayUtilityMethods} class. -*/ + * Testing utility methods in {@link ArrayUtilityMethods} class. + */ class ArrayUtilityMethodsTest { @Test void arraysSameTest() { - int[] arr1 = new int[] {1,4,2,6}; - int[] arr2 = new int[] {1,4,2,6}; + var arr1 = new int[]{1, 4, 2, 6}; + var arr2 = new int[]{1, 4, 2, 6}; assertTrue(ArrayUtilityMethods.arraysSame(arr1, arr2)); } @Test void matricesSameTest() { - int[][] matrix1 = new int[][] {{1,4,2,6},{5,8,6,7}}; - int[][] matrix2 = new int[][] {{1,4,2,6},{5,8,6,7}}; + var matrix1 = new int[][]{{1, 4, 2, 6}, {5, 8, 6, 7}}; + var matrix2 = new int[][]{{1, 4, 2, 6}, {5, 8, 6, 7}}; assertTrue(ArrayUtilityMethods.matricesSame(matrix1, matrix2)); } diff --git a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/ArrayTransposeMasterWorkerTest.java b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/ArrayTransposeMasterWorkerTest.java index b80d7881f..79838ed35 100644 --- a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/ArrayTransposeMasterWorkerTest.java +++ b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/ArrayTransposeMasterWorkerTest.java @@ -23,25 +23,38 @@ package com.iluwatar.masterworker.system; -import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.Test; -import com.iluwatar.masterworker.ArrayUtilityMethods; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.iluwatar.masterworker.ArrayInput; import com.iluwatar.masterworker.ArrayResult; +import com.iluwatar.masterworker.ArrayUtilityMethods; +import org.junit.jupiter.api.Test; /** -* Testing getResult method in {@link ArrayTransposeMasterWorker} class. -*/ + * Testing getResult method in {@link ArrayTransposeMasterWorker} class. + */ class ArrayTransposeMasterWorkerTest { @Test void getResultTest() { - ArrayTransposeMasterWorker atmw = new ArrayTransposeMasterWorker(); - int[][] matrix = new int[][] {{1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}}; - int[][] matrixTranspose = new int[][] {{1,1,1,1,1}, {2,2,2,2,2}, {3,3,3,3,3}, {4,4,4,4,4}, {5,5,5,5,5}}; - ArrayInput i = new ArrayInput(matrix); - ArrayResult r = (ArrayResult) atmw.getResult(i); + var atmw = new ArrayTransposeMasterWorker(); + var matrix = new int[][]{ + {1, 2, 3, 4, 5}, + {1, 2, 3, 4, 5}, + {1, 2, 3, 4, 5}, + {1, 2, 3, 4, 5}, + {1, 2, 3, 4, 5} + }; + var matrixTranspose = new int[][]{ + {1, 1, 1, 1, 1}, + {2, 2, 2, 2, 2}, + {3, 3, 3, 3, 3}, + {4, 4, 4, 4, 4}, + {5, 5, 5, 5, 5} + }; + var i = new ArrayInput(matrix); + var r = (ArrayResult) atmw.getResult(i); assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose)); - } + } } diff --git a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorkerTest.java b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorkerTest.java index 3e5f581b9..c4b210643 100644 --- a/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorkerTest.java +++ b/master-worker-pattern/src/test/java/com/iluwatar/masterworker/system/systemworkers/ArrayTransposeWorkerTest.java @@ -23,29 +23,29 @@ package com.iluwatar.masterworker.system.systemworkers; -import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.Test; -import com.iluwatar.masterworker.ArrayUtilityMethods; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.iluwatar.masterworker.ArrayInput; -import com.iluwatar.masterworker.ArrayResult; +import com.iluwatar.masterworker.ArrayUtilityMethods; import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster; +import org.junit.jupiter.api.Test; /** -* Testing executeOperation method in {@link ArrayTransposeWorker} class. -*/ + * Testing executeOperation method in {@link ArrayTransposeWorker} class. + */ class ArrayTransposeWorkerTest { @Test void executeOperationTest() { - ArrayTransposeMaster atm = new ArrayTransposeMaster(1); - ArrayTransposeWorker atw = new ArrayTransposeWorker(atm, 1); - int[][] matrix = new int[][] {{2,4}, {3,5}}; - int[][] matrixTranspose = new int[][] {{2,3}, {4,5}}; - ArrayInput i = new ArrayInput(matrix); + var atm = new ArrayTransposeMaster(1); + var atw = new ArrayTransposeWorker(atm, 1); + var matrix = new int[][]{{2, 4}, {3, 5}}; + var matrixTranspose = new int[][]{{2, 3}, {4, 5}}; + var i = new ArrayInput(matrix); atw.setReceivedData(atm, i); - ArrayResult r = atw.executeOperation(); + var r = atw.executeOperation(); assertTrue(ArrayUtilityMethods.matricesSame(r.data, matrixTranspose)); } - + } From 93e5570778e8b9acd5ebe8d29727a8ac96e1eab8 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:19:11 +0000 Subject: [PATCH 003/285] Java 11 migraiton: mediator pattern --- .../java/com/iluwatar/mediator/Action.java | 4 +- .../main/java/com/iluwatar/mediator/App.java | 8 +-- .../java/com/iluwatar/mediator/PartyImpl.java | 2 +- .../java/com/iluwatar/mediator/AppTest.java | 5 +- .../com/iluwatar/mediator/PartyImplTest.java | 7 +-- .../iluwatar/mediator/PartyMemberTest.java | 62 +++++++++---------- 6 files changed, 42 insertions(+), 46 deletions(-) diff --git a/mediator/src/main/java/com/iluwatar/mediator/Action.java b/mediator/src/main/java/com/iluwatar/mediator/Action.java index 66e1f42c4..1d93a384b 100644 --- a/mediator/src/main/java/com/iluwatar/mediator/Action.java +++ b/mediator/src/main/java/com/iluwatar/mediator/Action.java @@ -34,8 +34,8 @@ public enum Action { ENEMY("spotted enemies", "runs for cover"), NONE("", ""); - private String title; - private String description; + private final String title; + private final String description; Action(String title, String description) { this.title = title; diff --git a/mediator/src/main/java/com/iluwatar/mediator/App.java b/mediator/src/main/java/com/iluwatar/mediator/App.java index 9dbedb4ab..0e9021c0d 100644 --- a/mediator/src/main/java/com/iluwatar/mediator/App.java +++ b/mediator/src/main/java/com/iluwatar/mediator/App.java @@ -55,10 +55,10 @@ public class App { // create party and members Party party = new PartyImpl(); - Hobbit hobbit = new Hobbit(); - Wizard wizard = new Wizard(); - Rogue rogue = new Rogue(); - Hunter hunter = new Hunter(); + var hobbit = new Hobbit(); + var wizard = new Wizard(); + var rogue = new Rogue(); + var hunter = new Hunter(); // add party members party.addMember(hobbit); diff --git a/mediator/src/main/java/com/iluwatar/mediator/PartyImpl.java b/mediator/src/main/java/com/iluwatar/mediator/PartyImpl.java index 6384a2187..f842a0f39 100644 --- a/mediator/src/main/java/com/iluwatar/mediator/PartyImpl.java +++ b/mediator/src/main/java/com/iluwatar/mediator/PartyImpl.java @@ -39,7 +39,7 @@ public class PartyImpl implements Party { @Override public void act(PartyMember actor, Action action) { - for (PartyMember member : members) { + for (var member : members) { if (!member.equals(actor)) { member.partyAction(action); } diff --git a/mediator/src/test/java/com/iluwatar/mediator/AppTest.java b/mediator/src/test/java/com/iluwatar/mediator/AppTest.java index 3a55d51d8..23f2a72f2 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/AppTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/AppTest.java @@ -26,15 +26,12 @@ package com.iluwatar.mediator; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java index 5d2446545..d25562f84 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyImplTest.java @@ -43,10 +43,10 @@ public class PartyImplTest { */ @Test public void testPartyAction() { - final PartyMember partyMember1 = mock(PartyMember.class); - final PartyMember partyMember2 = mock(PartyMember.class); + final var partyMember1 = mock(PartyMember.class); + final var partyMember2 = mock(PartyMember.class); - final PartyImpl party = new PartyImpl(); + final var party = new PartyImpl(); party.addMember(partyMember1); party.addMember(partyMember2); @@ -58,7 +58,6 @@ public class PartyImplTest { verify(partyMember2).partyAction(Action.GOLD); verifyNoMoreInteractions(partyMember1, partyMember2); - } } diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java index 951f8e166..a0e722cfd 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java @@ -23,24 +23,24 @@ 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.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.slf4j.LoggerFactory; - -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.function.Supplier; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Stream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.LoggerFactory; + /** * Date: 12/19/15 - 10:13 PM * @@ -48,12 +48,12 @@ import static org.mockito.Mockito.verify; */ public class PartyMemberTest { - static Collection[]> dataProvider() { - return List.of( - new Supplier[]{Hobbit::new}, - new Supplier[]{Hunter::new}, - new Supplier[]{Rogue::new}, - new Supplier[]{Wizard::new} + static Stream dataProvider() { + return Stream.of( + Arguments.of((Supplier) Hobbit::new), + Arguments.of((Supplier) Hunter::new), + Arguments.of((Supplier) Rogue::new), + Arguments.of((Supplier) Wizard::new) ); } @@ -75,9 +75,9 @@ public class PartyMemberTest { @ParameterizedTest @MethodSource("dataProvider") public void testPartyAction(Supplier memberSupplier) { - final PartyMember member = memberSupplier.get(); + final var member = memberSupplier.get(); - for (final Action action : Action.values()) { + for (final var action : Action.values()) { member.partyAction(action); assertEquals(member.toString() + " " + action.getDescription(), appender.getLastMessage()); } @@ -91,16 +91,16 @@ public class PartyMemberTest { @ParameterizedTest @MethodSource("dataProvider") public void testAct(Supplier memberSupplier) { - final PartyMember member = memberSupplier.get(); + final var member = memberSupplier.get(); member.act(Action.GOLD); assertEquals(0, appender.getLogSize()); - final Party party = mock(Party.class); + final var party = mock(Party.class); member.joinedParty(party); assertEquals(member.toString() + " joins the party", appender.getLastMessage()); - for (final Action action : Action.values()) { + for (final var action : Action.values()) { member.act(action); assertEquals(member.toString() + " " + action.toString(), appender.getLastMessage()); verify(party).act(member, action); @@ -114,16 +114,16 @@ public class PartyMemberTest { */ @ParameterizedTest @MethodSource("dataProvider") - public void testToString(Supplier memberSupplier) throws Exception { - final PartyMember member = memberSupplier.get(); - final Class memberClass = member.getClass(); + public void testToString(Supplier memberSupplier) { + final var member = memberSupplier.get(); + final var memberClass = member.getClass(); assertEquals(memberClass.getSimpleName(), member.toString()); } - private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private static class InMemoryAppender extends AppenderBase { + private final List log = new LinkedList<>(); - public InMemoryAppender(Class clazz) { + public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); start(); } From a00622c656be2593ec632bdc08573fdc4ed5364d Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:21:48 +0000 Subject: [PATCH 004/285] Java 11 migraiton: memento --- .../src/main/java/com/iluwatar/memento/App.java | 4 ++-- .../src/main/java/com/iluwatar/memento/Star.java | 4 ++-- .../main/java/com/iluwatar/memento/StarType.java | 2 +- .../test/java/com/iluwatar/memento/AppTest.java | 5 +---- .../test/java/com/iluwatar/memento/StarTest.java | 14 +++++++------- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/memento/src/main/java/com/iluwatar/memento/App.java b/memento/src/main/java/com/iluwatar/memento/App.java index af57d8d4a..77cc0f214 100644 --- a/memento/src/main/java/com/iluwatar/memento/App.java +++ b/memento/src/main/java/com/iluwatar/memento/App.java @@ -52,9 +52,9 @@ public class App { * Program entry point. */ public static void main(String[] args) { - Stack states = new Stack<>(); + var states = new Stack(); - Star star = new Star(StarType.SUN, 10000000, 500000); + var star = new Star(StarType.SUN, 10000000, 500000); LOGGER.info(star.toString()); states.add(star.getMemento()); star.timePasses(); diff --git a/memento/src/main/java/com/iluwatar/memento/Star.java b/memento/src/main/java/com/iluwatar/memento/Star.java index ebeea28f2..aac58b817 100644 --- a/memento/src/main/java/com/iluwatar/memento/Star.java +++ b/memento/src/main/java/com/iluwatar/memento/Star.java @@ -71,7 +71,7 @@ public class Star { StarMemento getMemento() { - StarMementoInternal state = new StarMementoInternal(); + var state = new StarMementoInternal(); state.setAgeYears(ageYears); state.setMassTons(massTons); state.setType(type); @@ -81,7 +81,7 @@ public class Star { void setMemento(StarMemento memento) { - StarMementoInternal state = (StarMementoInternal) memento; + var state = (StarMementoInternal) memento; this.type = state.getType(); this.ageYears = state.getAgeYears(); this.massTons = state.getMassTons(); diff --git a/memento/src/main/java/com/iluwatar/memento/StarType.java b/memento/src/main/java/com/iluwatar/memento/StarType.java index 507cd506b..339f05f9f 100644 --- a/memento/src/main/java/com/iluwatar/memento/StarType.java +++ b/memento/src/main/java/com/iluwatar/memento/StarType.java @@ -31,7 +31,7 @@ public enum StarType { SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( "dead star"), UNDEFINED(""); - private String title; + private final String title; StarType(String title) { this.title = title; diff --git a/memento/src/test/java/com/iluwatar/memento/AppTest.java b/memento/src/test/java/com/iluwatar/memento/AppTest.java index 074de2c41..e0448c289 100644 --- a/memento/src/test/java/com/iluwatar/memento/AppTest.java +++ b/memento/src/test/java/com/iluwatar/memento/AppTest.java @@ -26,15 +26,12 @@ package com.iluwatar.memento; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/memento/src/test/java/com/iluwatar/memento/StarTest.java b/memento/src/test/java/com/iluwatar/memento/StarTest.java index 40adb99e1..aab59e9c3 100644 --- a/memento/src/test/java/com/iluwatar/memento/StarTest.java +++ b/memento/src/test/java/com/iluwatar/memento/StarTest.java @@ -23,10 +23,10 @@ package com.iluwatar.memento; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + /** * Date: 12/20/15 - 10:08 AM * @@ -39,7 +39,7 @@ public class StarTest { */ @Test public void testTimePasses() { - final Star star = new Star(StarType.SUN, 1, 2); + final var star = new Star(StarType.SUN, 1, 2); assertEquals("sun age: 1 years mass: 2 tons", star.toString()); star.timePasses(); @@ -66,16 +66,16 @@ public class StarTest { */ @Test public void testSetMemento() { - final Star star = new Star(StarType.SUN, 1, 2); - final StarMemento firstMemento = star.getMemento(); + final var star = new Star(StarType.SUN, 1, 2); + final var firstMemento = star.getMemento(); assertEquals("sun age: 1 years mass: 2 tons", star.toString()); star.timePasses(); - final StarMemento secondMemento = star.getMemento(); + final var secondMemento = star.getMemento(); assertEquals("red giant age: 2 years mass: 16 tons", star.toString()); star.timePasses(); - final StarMemento thirdMemento = star.getMemento(); + final var thirdMemento = star.getMemento(); assertEquals("white dwarf age: 4 years mass: 128 tons", star.toString()); star.timePasses(); From edcb520d087bb12a5d04bc07810da33069bdea38 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:30:18 +0000 Subject: [PATCH 005/285] Java 11 migraiton: model-view-controller --- .../iluwatar/model/view/controller/App.java | 6 +-- .../model/view/controller/Fatigue.java | 2 +- .../view/controller/GiantController.java | 7 +++- .../model/view/controller/Health.java | 2 +- .../model/view/controller/Nourishment.java | 2 +- .../model/view/controller/AppTest.java | 5 +-- .../view/controller/GiantControllerTest.java | 37 ++++++++++--------- .../model/view/controller/GiantModelTest.java | 25 +++++++------ .../model/view/controller/GiantViewTest.java | 11 +++--- 9 files changed, 51 insertions(+), 46 deletions(-) diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/App.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/App.java index 4607f009d..cabc4d96f 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/App.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/App.java @@ -47,9 +47,9 @@ public class App { */ public static void main(String[] args) { // create model, view and controller - GiantModel giant = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); - GiantView view = new GiantView(); - GiantController controller = new GiantController(giant, view); + var giant = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + var view = new GiantView(); + var controller = new GiantController(giant, view); // initial display controller.updateView(); // controller receives some interactions that affect the giant diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java index b1663df1f..2b7ca3999 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java @@ -30,7 +30,7 @@ public enum Fatigue { ALERT("alert"), TIRED("tired"), SLEEPING("sleeping"); - private String title; + private final String title; Fatigue(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java index e66608117..f96113574 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java @@ -28,14 +28,15 @@ package com.iluwatar.model.view.controller; */ public class GiantController { - private GiantModel giant; - private GiantView view; + private final GiantModel giant; + private final GiantView view; public GiantController(GiantModel giant, GiantView view) { this.giant = giant; this.view = view; } + @SuppressWarnings("UnusedReturnValue") public Health getHealth() { return giant.getHealth(); } @@ -44,6 +45,7 @@ public class GiantController { this.giant.setHealth(health); } + @SuppressWarnings("UnusedReturnValue") public Fatigue getFatigue() { return giant.getFatigue(); } @@ -52,6 +54,7 @@ public class GiantController { this.giant.setFatigue(fatigue); } + @SuppressWarnings("UnusedReturnValue") public Nourishment getNourishment() { return giant.getNourishment(); } diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java index 30b3b2b90..a8346b9c7 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java @@ -30,7 +30,7 @@ public enum Health { HEALTHY("healthy"), WOUNDED("wounded"), DEAD("dead"); - private String title; + private final String title; Health(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java index 3ced564cc..c61d2de79 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java @@ -30,7 +30,7 @@ public enum Nourishment { SATURATED("saturated"), HUNGRY("hungry"), STARVING("starving"); - private String title; + private final String title; Nourishment(String title) { this.title = title; diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java index e6d2d9a0b..69dc19f1c 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java @@ -26,15 +26,12 @@ package com.iluwatar.model.view.controller; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java index a2f42a80d..d106d0944 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantControllerTest.java @@ -23,13 +23,13 @@ package com.iluwatar.model.view.controller; -import org.junit.jupiter.api.Test; - import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import org.junit.jupiter.api.Test; + /** * Date: 12/20/15 - 2:19 PM * @@ -42,19 +42,20 @@ public class GiantControllerTest { */ @Test public void testSetHealth() { - final GiantModel model = mock(GiantModel.class); - final GiantView view = mock(GiantView.class); - final GiantController controller = new GiantController(model, view); + final var model = mock(GiantModel.class); + final var view = mock(GiantView.class); + final var controller = new GiantController(model, view); verifyZeroInteractions(model, view); - for (final Health health : Health.values()) { + for (final var health : Health.values()) { controller.setHealth(health); verify(model).setHealth(health); verifyZeroInteractions(view); } controller.getHealth(); + //noinspection ResultOfMethodCallIgnored verify(model).getHealth(); verifyNoMoreInteractions(model, view); @@ -65,19 +66,20 @@ public class GiantControllerTest { */ @Test public void testSetFatigue() { - final GiantModel model = mock(GiantModel.class); - final GiantView view = mock(GiantView.class); - final GiantController controller = new GiantController(model, view); + final var model = mock(GiantModel.class); + final var view = mock(GiantView.class); + final var controller = new GiantController(model, view); verifyZeroInteractions(model, view); - for (final Fatigue fatigue : Fatigue.values()) { + for (final var fatigue : Fatigue.values()) { controller.setFatigue(fatigue); verify(model).setFatigue(fatigue); verifyZeroInteractions(view); } controller.getFatigue(); + //noinspection ResultOfMethodCallIgnored verify(model).getFatigue(); verifyNoMoreInteractions(model, view); @@ -88,19 +90,20 @@ public class GiantControllerTest { */ @Test public void testSetNourishment() { - final GiantModel model = mock(GiantModel.class); - final GiantView view = mock(GiantView.class); - final GiantController controller = new GiantController(model, view); + final var model = mock(GiantModel.class); + final var view = mock(GiantView.class); + final var controller = new GiantController(model, view); verifyZeroInteractions(model, view); - for (final Nourishment nourishment : Nourishment.values()) { + for (final var nourishment : Nourishment.values()) { controller.setNourishment(nourishment); verify(model).setNourishment(nourishment); verifyZeroInteractions(view); } controller.getNourishment(); + //noinspection ResultOfMethodCallIgnored verify(model).getNourishment(); verifyNoMoreInteractions(model, view); @@ -108,9 +111,9 @@ public class GiantControllerTest { @Test public void testUpdateView() { - final GiantModel model = mock(GiantModel.class); - final GiantView view = mock(GiantView.class); - final GiantController controller = new GiantController(model, view); + final var model = mock(GiantModel.class); + final var view = mock(GiantView.class); + final var controller = new GiantController(model, view); verifyZeroInteractions(model, view); diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java index a566010cd..c1a86b750 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java @@ -23,10 +23,10 @@ package com.iluwatar.model.view.controller; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + /** * Date: 12/20/15 - 2:10 PM * @@ -39,12 +39,13 @@ public class GiantModelTest { */ @Test public void testSetHealth() { - final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + final var model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.HUNGRY); assertEquals(Health.HEALTHY, model.getHealth()); - for (final Health health : Health.values()) { + for (final var health : Health.values()) { model.setHealth(health); assertEquals(health, model.getHealth()); - assertEquals("The giant looks " + health.toString() + ", alert and saturated.", model.toString()); + assertEquals("The giant looks " + health.toString() + ", alert and saturated.", model + .toString()); } } @@ -53,12 +54,13 @@ public class GiantModelTest { */ @Test public void testSetFatigue() { - final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + final var model = new GiantModel(Health.WOUNDED, Fatigue.ALERT, Nourishment.SATURATED); assertEquals(Fatigue.ALERT, model.getFatigue()); - for (final Fatigue fatigue : Fatigue.values()) { + for (final var fatigue : Fatigue.values()) { model.setFatigue(fatigue); assertEquals(fatigue, model.getFatigue()); - assertEquals("The giant looks healthy, " + fatigue.toString() + " and saturated.", model.toString()); + assertEquals("The giant looks healthy, " + fatigue.toString() + " and saturated.", model + .toString()); } } @@ -67,12 +69,13 @@ public class GiantModelTest { */ @Test public void testSetNourishment() { - final GiantModel model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); + final var model = new GiantModel(Health.HEALTHY, Fatigue.TIRED, Nourishment.SATURATED); assertEquals(Nourishment.SATURATED, model.getNourishment()); - for (final Nourishment nourishment : Nourishment.values()) { + for (final var nourishment : Nourishment.values()) { model.setNourishment(nourishment); assertEquals(nourishment, model.getNourishment()); - assertEquals("The giant looks healthy, alert and " + nourishment.toString() + ".", model.toString()); + assertEquals("The giant looks healthy, alert and " + nourishment.toString() + ".", model + .toString()); } } diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java index a3e33f9dd..c6314c1dd 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java @@ -31,7 +31,6 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; import java.util.LinkedList; import java.util.List; - import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -62,9 +61,9 @@ public class GiantViewTest { */ @Test public void testDisplayGiant() { - final GiantView view = new GiantView(); + final var view = new GiantView(); - final GiantModel model = mock(GiantModel.class); + final var model = mock(GiantModel.class); view.displayGiant(model); assertEquals(model.toString(), appender.getLastMessage()); @@ -74,10 +73,10 @@ public class GiantViewTest { /** * Logging Appender Implementation */ - public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + public static class InMemoryAppender extends AppenderBase { + private final List log = new LinkedList<>(); - public InMemoryAppender(Class clazz) { + public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); start(); } From 99c70af16aecd2f9bb57ff3e484c38188ecd9e62 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:35:33 +0000 Subject: [PATCH 006/285] Java 11 migraiton: model-view-presenter --- .../iluwatar/model/view/presenter/App.java | 6 +-- .../model/view/presenter/FileLoader.java | 16 +++---- .../view/presenter/FileSelectorJFrame.java | 45 +++++++------------ .../view/presenter/FileSelectorPresenter.java | 4 +- .../model/view/presenter/AppTest.java | 5 +-- .../model/view/presenter/FileLoaderTest.java | 8 ++-- .../presenter/FileSelectorPresenterTest.java | 8 ++-- 7 files changed, 34 insertions(+), 58 deletions(-) diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/App.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/App.java index 43984e847..ac3b83927 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/App.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/App.java @@ -44,9 +44,9 @@ public class App { * @param args command line args */ public static void main(String[] args) { - FileLoader loader = new FileLoader(); - FileSelectorJFrame frame = new FileSelectorJFrame(); - FileSelectorPresenter presenter = new FileSelectorPresenter(frame); + var loader = new FileLoader(); + var frame = new FileSelectorJFrame(); + var presenter = new FileSelectorPresenter(frame); presenter.setLoader(loader); presenter.start(); } diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java index 9c01b2044..7dd5dd215 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileLoader.java @@ -27,6 +27,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.Serializable; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,18 +60,11 @@ public class FileLoader implements Serializable { * Loads the data of the file specified. */ public String loadData() { - String dataFileName = this.fileName; - try (BufferedReader br = new BufferedReader(new FileReader(new File(dataFileName)))) { - StringBuilder sb = new StringBuilder(); - String line; - - while ((line = br.readLine()) != null) { - sb.append(line).append('\n'); - } - + var dataFileName = this.fileName; + try (var br = new BufferedReader(new FileReader(new File(dataFileName)))) { + var result = br.lines().collect(Collectors.joining("\n")); this.loaded = true; - - return sb.toString(); + return result; } catch (Exception e) { LOGGER.error("File {} does not exist", dataFileName); } diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 77523ccaa..1d59b5d8c 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -48,37 +48,22 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /** * The "OK" button for loading the file. */ - private JButton ok; + private final JButton ok; /** * The cancel button. */ - private JButton cancel; - - /** - * The information label. - */ - private JLabel info; - - /** - * The contents label. - */ - private JLabel contents; + private final JButton cancel; /** * The text field for giving the name of the file that we want to open. */ - private JTextField input; + private final JTextField input; /** * A text area that will keep the contents of the file opened. */ - private JTextArea area; - - /** - * The panel that will hold our widgets. - */ - private JPanel panel; + private final JTextArea area; /** * The Presenter component that the frame will interact with. @@ -102,7 +87,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /* * Add the panel. */ - this.panel = new JPanel(); + var panel = new JPanel(); panel.setLayout(null); this.add(panel); panel.setBounds(0, 0, 500, 200); @@ -111,32 +96,32 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /* * Add the info label. */ - this.info = new JLabel("File Name :"); - this.panel.add(info); + var info = new JLabel("File Name :"); + panel.add(info); info.setBounds(30, 10, 100, 30); /* * Add the contents label. */ - this.contents = new JLabel("File contents :"); - this.panel.add(contents); - this.contents.setBounds(30, 100, 120, 30); + var contents = new JLabel("File contents :"); + panel.add(contents); + contents.setBounds(30, 100, 120, 30); /* * Add the text field. */ this.input = new JTextField(100); - this.panel.add(input); + panel.add(input); this.input.setBounds(150, 15, 200, 20); /* * Add the text area. */ this.area = new JTextArea(100, 100); - JScrollPane pane = new JScrollPane(area); + var pane = new JScrollPane(area); pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - this.panel.add(pane); + panel.add(pane); this.area.setEditable(false); pane.setBounds(150, 100, 250, 80); @@ -144,7 +129,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti * Add the OK button. */ this.ok = new JButton("OK"); - this.panel.add(ok); + panel.add(ok); this.ok.setBounds(250, 50, 100, 25); this.ok.addActionListener(this); @@ -152,7 +137,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti * Add the cancel button. */ this.cancel = new JButton("Cancel"); - this.panel.add(this.cancel); + panel.add(this.cancel); this.cancel.setBounds(380, 50, 100, 25); this.cancel.addActionListener(this); diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java index 35e1c0076..5cd6580d9 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java @@ -41,7 +41,7 @@ public class FileSelectorPresenter implements Serializable { /** * The View component that the presenter interacts with. */ - private FileSelectorView view; + private final FileSelectorView view; /** * The Model component that the presenter interacts with. @@ -91,7 +91,7 @@ public class FileSelectorPresenter implements Serializable { } if (loader.fileExists()) { - String data = loader.loadData(); + var data = loader.loadData(); view.displayData(data); } else { view.showMessage("The file specified does not exist."); diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java index 00e35ae1b..4db990a2d 100644 --- a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java @@ -26,16 +26,13 @@ package com.iluwatar.model.view.presenter; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java index a63ca5ae8..3787cd20b 100644 --- a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileLoaderTest.java @@ -23,10 +23,10 @@ package com.iluwatar.model.view.presenter; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + /** * Date: 12/21/15 - 12:12 PM * @@ -35,8 +35,8 @@ import static org.junit.jupiter.api.Assertions.assertNull; public class FileLoaderTest { @Test - public void testLoadData() throws Exception { - final FileLoader fileLoader = new FileLoader(); + public void testLoadData() { + final var fileLoader = new FileLoader(); fileLoader.setFileName("non-existing-file"); assertNull(fileLoader.loadData()); } diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java index fdc19398d..238d3a135 100644 --- a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/FileSelectorPresenterTest.java @@ -23,14 +23,14 @@ package com.iluwatar.model.view.presenter; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + /** * This test case is responsible for testing our application by taking advantage of the * Model-View-Controller architectural pattern. @@ -79,7 +79,7 @@ public class FileSelectorPresenterTest { */ @Test public void updateFileNameToLoader() { - String expectedFile = "Stamatis"; + var expectedFile = "Stamatis"; stub.setFileName(expectedFile); presenter.start(); From f1b27ef5c78eb379ca5f2ef539cca8c533ddc0a8 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:38:00 +0000 Subject: [PATCH 007/285] Java 11 migraiton: module --- module/pom.xml | 69 ++++++++++--------- .../main/java/com/iluwatar/module/App.java | 6 +- .../java/com/iluwatar/module/AppTest.java | 6 +- .../iluwatar/module/FileLoggerModuleTest.java | 41 ++++++----- 4 files changed, 59 insertions(+), 63 deletions(-) diff --git a/module/pom.xml b/module/pom.xml index 25ad707eb..5d9a6d529 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -23,38 +23,39 @@ THE SOFTWARE. --> - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.23.0-SNAPSHOT - - module - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.module.App - - - - - - - - + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.23.0-SNAPSHOT + + module + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.module.App + + + + + + + + diff --git a/module/src/main/java/com/iluwatar/module/App.java b/module/src/main/java/com/iluwatar/module/App.java index 1b6cbbd23..77034d76b 100644 --- a/module/src/main/java/com/iluwatar/module/App.java +++ b/module/src/main/java/com/iluwatar/module/App.java @@ -65,10 +65,8 @@ public class App { /** * Following method is main executor. - * - * @param args for providing default program arguments */ - public static void execute(final String... args) { + public static void execute() { /* Send logs on file system */ fileLoggerModule.printString("Message"); @@ -88,7 +86,7 @@ public class App { */ public static void main(final String... args) throws FileNotFoundException { prepare(); - execute(args); + execute(); unprepare(); } } diff --git a/module/src/test/java/com/iluwatar/module/AppTest.java b/module/src/test/java/com/iluwatar/module/AppTest.java index 88fa4c68c..8dcfd565e 100644 --- a/module/src/test/java/com/iluwatar/module/AppTest.java +++ b/module/src/test/java/com/iluwatar/module/AppTest.java @@ -23,9 +23,8 @@ package com.iluwatar.module; -import org.junit.jupiter.api.Test; - import java.io.FileNotFoundException; +import org.junit.jupiter.api.Test; /** * Tests that Module example runs without errors. @@ -34,7 +33,6 @@ public final class AppTest { @Test public void test() throws FileNotFoundException { - final String[] args = {}; - App.main(args); + App.main(); } } diff --git a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java index e88b466f2..6497aa89d 100644 --- a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java +++ b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java @@ -23,17 +23,16 @@ package com.iluwatar.module; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The Module pattern can be considered a Creational pattern and a Structural pattern. It manages @@ -58,14 +57,14 @@ public final class FileLoggerModuleTest { /** * This test verify that 'MESSAGE' is perfectly printed in output file - * + * * @throws IOException if program is not able to find log files (output.txt and error.txt) */ @Test public void testFileMessage() throws IOException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -82,14 +81,14 @@ public final class FileLoggerModuleTest { /** * This test verify that nothing is printed in output file - * + * * @throws IOException if program is not able to find log files (output.txt and error.txt) */ @Test public void testNoFileMessage() throws IOException { - /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + /* Get singleton instance of File Logger Module */ + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -103,15 +102,15 @@ public final class FileLoggerModuleTest { /** * This test verify that 'ERROR' is perfectly printed in error file - * + * * @throws FileNotFoundException if program is not able to find log files (output.txt and - * error.txt) + * error.txt) */ @Test public void testFileErrorMessage() throws FileNotFoundException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -122,21 +121,21 @@ public final class FileLoggerModuleTest { /* Test if 'Message' is printed in file */ assertEquals(ERROR, readFirstLine(ERROR_FILE)); - /* Unprepare to cleanup the modules */ + /* Un-prepare to cleanup the modules */ fileLoggerModule.unprepare(); } /** * This test verify that nothing is printed in error file - * + * * @throws FileNotFoundException if program is not able to find log files (output.txt and - * error.txt) + * error.txt) */ @Test public void testNoFileErrorMessage() throws FileNotFoundException { /* Get singletong instance of File Logger Module */ - final FileLoggerModule fileLoggerModule = FileLoggerModule.getSingleton(); + final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ fileLoggerModule.prepare(); @@ -150,14 +149,14 @@ public final class FileLoggerModuleTest { /** * Utility method to read first line of a file - * + * * @param file as file name to be read * @return a string value as first line in file */ - private static final String readFirstLine(final String file) { + private static String readFirstLine(final String file) { String firstLine = null; - try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + try (var bufferedReader = new BufferedReader(new FileReader(file))) { while (bufferedReader.ready()) { From a142c06048117a6352994eeb3995b6d37e9a3b97 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:45:54 +0000 Subject: [PATCH 008/285] Java 11 migraiton: monad --- .../src/main/java/com/iluwatar/monad/App.java | 9 ++--- .../main/java/com/iluwatar/monad/User.java | 8 ++-- .../java/com/iluwatar/monad/Validator.java | 19 +++++---- .../test/java/com/iluwatar/monad/AppTest.java | 3 +- .../java/com/iluwatar/monad/MonadTest.java | 39 +++++++++++-------- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/monad/src/main/java/com/iluwatar/monad/App.java b/monad/src/main/java/com/iluwatar/monad/App.java index ccb42edd0..bb3315064 100644 --- a/monad/src/main/java/com/iluwatar/monad/App.java +++ b/monad/src/main/java/com/iluwatar/monad/App.java @@ -41,9 +41,8 @@ import org.slf4j.LoggerFactory; * instance of a plain object with {@link Validator#of(Object)} and validates it {@link * Validator#validate(Function, Predicate, String)} against given predicates. * - *

As a validation result {@link Validator#get()} it either returns valid object {@link - * Validator#t} or throws a list of exceptions {@link Validator#exceptions} collected during - * validation. + *

As a validation result {@link Validator#get()} either returns valid object + * or throws {@link IllegalStateException} with list of exceptions collected during validation. */ public class App { @@ -55,10 +54,10 @@ public class App { * @param args command line args */ public static void main(String[] args) { - User user = new User("user", 24, Sex.FEMALE, "foobar.com"); + var user = new User("user", 24, Sex.FEMALE, "foobar.com"); LOGGER.info(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null") .validate(User::getName, name -> !name.isEmpty(), "name is empty") - .validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'") + .validate(User::getEmail, email -> !email.contains("@"), "email doesn't contains '@'") .validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get() .toString()); } diff --git a/monad/src/main/java/com/iluwatar/monad/User.java b/monad/src/main/java/com/iluwatar/monad/User.java index 77766d1aa..f67009bc3 100644 --- a/monad/src/main/java/com/iluwatar/monad/User.java +++ b/monad/src/main/java/com/iluwatar/monad/User.java @@ -28,10 +28,10 @@ package com.iluwatar.monad; */ public class User { - private String name; - private int age; - private Sex sex; - private String email; + private final String name; + private final int age; + private final Sex sex; + private final String email; /** * Constructor. diff --git a/monad/src/main/java/com/iluwatar/monad/Validator.java b/monad/src/main/java/com/iluwatar/monad/Validator.java index 2d1f1bdab..47acc8a42 100644 --- a/monad/src/main/java/com/iluwatar/monad/Validator.java +++ b/monad/src/main/java/com/iluwatar/monad/Validator.java @@ -85,18 +85,21 @@ public class Validator { } /** - * Extension for the {@link Validator#validate(Function, Predicate, String)} method, dedicated for - * objects, that need to be projected before requested validation. + * Extension for the {@link Validator#validate(Predicate, String)} method, dedicated for objects, + * that need to be projected before requested validation. * * @param projection function that gets an objects, and returns projection representing element to * be validated. - * @param validation see {@link Validator#validate(Function, Predicate, String)} - * @param message see {@link Validator#validate(Function, Predicate, String)} - * @param see {@link Validator#validate(Function, Predicate, String)} + * @param validation see {@link Validator#validate(Predicate, String)} + * @param message see {@link Validator#validate(Predicate, String)} + * @param see {@link Validator#validate(Predicate, String)} * @return this */ - public Validator validate(Function projection, Predicate validation, - String message) { + public Validator validate( + Function projection, + Predicate validation, + String message + ) { return validate(projection.andThen(validation::test)::apply, message); } @@ -110,7 +113,7 @@ public class Validator { if (exceptions.isEmpty()) { return obj; } - IllegalStateException e = new IllegalStateException(); + var e = new IllegalStateException(); exceptions.forEach(e::addSuppressed); throw e; } diff --git a/monad/src/test/java/com/iluwatar/monad/AppTest.java b/monad/src/test/java/com/iluwatar/monad/AppTest.java index f4d89a7cd..d56270173 100644 --- a/monad/src/test/java/com/iluwatar/monad/AppTest.java +++ b/monad/src/test/java/com/iluwatar/monad/AppTest.java @@ -32,8 +32,7 @@ public class AppTest { @Test public void testMain() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/monad/src/test/java/com/iluwatar/monad/MonadTest.java b/monad/src/test/java/com/iluwatar/monad/MonadTest.java index d1bdd7487..afd5b50f8 100644 --- a/monad/src/test/java/com/iluwatar/monad/MonadTest.java +++ b/monad/src/test/java/com/iluwatar/monad/MonadTest.java @@ -23,13 +23,12 @@ package com.iluwatar.monad; -import org.junit.jupiter.api.Test; - -import java.util.Objects; - import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.Objects; +import org.junit.jupiter.api.Test; + /** * Test for Monad Pattern */ @@ -37,27 +36,33 @@ public class MonadTest { @Test public void testForInvalidName() { - User tom = new User(null, 21, Sex.MALE, "tom@foo.bar"); - assertThrows(IllegalStateException.class, () -> { - Validator.of(tom).validate(User::getName, Objects::nonNull, "name cannot be null").get(); - }); + var tom = new User(null, 21, Sex.MALE, "tom@foo.bar"); + assertThrows( + IllegalStateException.class, + () -> Validator.of(tom) + .validate(User::getName, Objects::nonNull, "name cannot be null") + .get() + ); } @Test public void testForInvalidAge() { - User john = new User("John", 17, Sex.MALE, "john@qwe.bar"); - assertThrows(IllegalStateException.class, () -> { - Validator.of(john).validate(User::getName, Objects::nonNull, "name cannot be null") - .validate(User::getAge, age -> age > 21, "user is underaged") - .get(); - }); + var john = new User("John", 17, Sex.MALE, "john@qwe.bar"); + assertThrows( + IllegalStateException.class, + () -> Validator.of(john) + .validate(User::getName, Objects::nonNull, "name cannot be null") + .validate(User::getAge, age -> age > 21, "user is underage") + .get() + ); } @Test public void testForValid() { - User sarah = new User("Sarah", 42, Sex.FEMALE, "sarah@det.org"); - User validated = Validator.of(sarah).validate(User::getName, Objects::nonNull, "name cannot be null") - .validate(User::getAge, age -> age > 21, "user is underaged") + var sarah = new User("Sarah", 42, Sex.FEMALE, "sarah@det.org"); + var validated = Validator.of(sarah) + .validate(User::getName, Objects::nonNull, "name cannot be null") + .validate(User::getAge, age -> age > 21, "user is underage") .validate(User::getSex, sex -> sex == Sex.FEMALE, "user is not female") .validate(User::getEmail, email -> email.contains("@"), "email does not contain @ sign") .get(); From 109d33c710fbb1db43bf2ecf6354682041f141b5 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:49:00 +0000 Subject: [PATCH 009/285] Java 11 migraiton: monostate --- .../src/main/java/com/iluwatar/monostate/App.java | 6 +++--- .../java/com/iluwatar/monostate/LoadBalancer.java | 6 +++--- .../test/java/com/iluwatar/monostate/AppTest.java | 3 +-- .../com/iluwatar/monostate/LoadBalancerTest.java | 12 ++++++------ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/monostate/src/main/java/com/iluwatar/monostate/App.java b/monostate/src/main/java/com/iluwatar/monostate/App.java index 64cb38461..9f5b2c173 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/App.java +++ b/monostate/src/main/java/com/iluwatar/monostate/App.java @@ -30,7 +30,7 @@ package com.iluwatar.monostate; * *

In the following example, The {@link LoadBalancer} class represents the app's logic. It * contains a series of Servers, which can handle requests of type {@link Request}. Two instances of - * LoadBalacer are created. When a request is made to a server via the first LoadBalancer the state + * LoadBalancer are created. When a request is made to a server via the first LoadBalancer the state * change in the first load balancer affects the second. So if the first LoadBalancer selects the * Server 1, the second LoadBalancer on a new request will select the Second server. If a third * LoadBalancer is created and a new request is made to it, then it will select the third server as @@ -43,8 +43,8 @@ public class App { * @param args command line args */ public static void main(String[] args) { - LoadBalancer loadBalancer1 = new LoadBalancer(); - LoadBalancer loadBalancer2 = new LoadBalancer(); + var loadBalancer1 = new LoadBalancer(); + var loadBalancer2 = new LoadBalancer(); loadBalancer1.serverRequest(new Request("Hello")); loadBalancer2.serverRequest(new Request("Hello World")); } diff --git a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java index 8546ae177..7a784f514 100644 --- a/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java +++ b/monostate/src/main/java/com/iluwatar/monostate/LoadBalancer.java @@ -38,8 +38,8 @@ public class LoadBalancer { private static int lastServedId; static { - int id = 0; - for (int port : new int[]{8080, 8081, 8082, 8083, 8084}) { + var id = 0; + for (var port : new int[]{8080, 8081, 8082, 8083, 8084}) { SERVERS.add(new Server("localhost", port, ++id)); } } @@ -69,7 +69,7 @@ public class LoadBalancer { if (lastServedId >= SERVERS.size()) { lastServedId = 0; } - Server server = SERVERS.get(lastServedId++); + var server = SERVERS.get(lastServedId++); server.serve(request); } diff --git a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java index c914f136e..d17a56bb9 100644 --- a/monostate/src/test/java/com/iluwatar/monostate/AppTest.java +++ b/monostate/src/test/java/com/iluwatar/monostate/AppTest.java @@ -32,8 +32,7 @@ public class AppTest { @Test public void testMain() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java index 736bf6ea6..d62c029e2 100644 --- a/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java +++ b/monostate/src/test/java/com/iluwatar/monostate/LoadBalancerTest.java @@ -44,8 +44,8 @@ public class LoadBalancerTest { @Test public void testSameStateAmongstAllInstances() { - final LoadBalancer firstBalancer = new LoadBalancer(); - final LoadBalancer secondBalancer = new LoadBalancer(); + final var firstBalancer = new LoadBalancer(); + final var secondBalancer = new LoadBalancer(); firstBalancer.addServer(new Server("localhost", 8085, 6)); // Both should have the same number of servers. assertEquals(firstBalancer.getNoOfServers(), secondBalancer.getNoOfServers()); @@ -55,18 +55,18 @@ public class LoadBalancerTest { @Test public void testServe() { - final Server server = mock(Server.class); + final var server = mock(Server.class); when(server.getHost()).thenReturn("testhost"); when(server.getPort()).thenReturn(1234); doNothing().when(server).serve(any(Request.class)); - final LoadBalancer loadBalancer = new LoadBalancer(); + final var loadBalancer = new LoadBalancer(); loadBalancer.addServer(server); verifyZeroInteractions(server); - final Request request = new Request("test"); - for (int i = 0; i < loadBalancer.getNoOfServers() * 2; i++) { + final var request = new Request("test"); + for (var i = 0; i < loadBalancer.getNoOfServers() * 2; i++) { loadBalancer.serverRequest(request); } From 9b105d770df2ca56ffd725e88fdbf17666e7cd1b Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:51:37 +0000 Subject: [PATCH 010/285] Java 11 migraiton: multiton --- .../src/main/java/com/iluwatar/multiton/Nazgul.java | 2 +- .../main/java/com/iluwatar/multiton/NazgulEnum.java | 12 +++++++++--- .../main/java/com/iluwatar/multiton/NazgulName.java | 12 +++++++++--- .../src/test/java/com/iluwatar/multiton/AppTest.java | 5 +---- .../java/com/iluwatar/multiton/NazgulEnumTest.java | 8 ++++---- .../test/java/com/iluwatar/multiton/NazgulTest.java | 4 ++-- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java index f55f85aca..bd1fc70ef 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java +++ b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java @@ -31,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class Nazgul { - private static Map nazguls; + private static final Map nazguls; private NazgulName name; diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java index 5b5c48d66..bb1454b9f 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java @@ -27,7 +27,13 @@ package com.iluwatar.multiton; * enum based multiton implementation. */ public enum NazgulEnum { - - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; - + KHAMUL, + MURAZOR, + DWAR, + JI_INDUR, + AKHORAHIL, + HOARMURATH, + ADUNAPHEL, + REN, + UVATHA } diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java index c7865dceb..cce19c6ff 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java @@ -27,7 +27,13 @@ package com.iluwatar.multiton; * Each Nazgul has different {@link NazgulName}. */ public enum NazgulName { - - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; - + KHAMUL, + MURAZOR, + DWAR, + JI_INDUR, + AKHORAHIL, + HOARMURATH, + ADUNAPHEL, + REN, + UVATHA } diff --git a/multiton/src/test/java/com/iluwatar/multiton/AppTest.java b/multiton/src/test/java/com/iluwatar/multiton/AppTest.java index f577b7f07..0496ebdaf 100644 --- a/multiton/src/test/java/com/iluwatar/multiton/AppTest.java +++ b/multiton/src/test/java/com/iluwatar/multiton/AppTest.java @@ -26,15 +26,12 @@ package com.iluwatar.multiton; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/multiton/src/test/java/com/iluwatar/multiton/NazgulEnumTest.java b/multiton/src/test/java/com/iluwatar/multiton/NazgulEnumTest.java index 6668874f4..4d107a181 100644 --- a/multiton/src/test/java/com/iluwatar/multiton/NazgulEnumTest.java +++ b/multiton/src/test/java/com/iluwatar/multiton/NazgulEnumTest.java @@ -39,10 +39,10 @@ class NazgulEnumTest { */ @Test public void testTheSameObjectIsReturnedWithMultipleCalls() { - for (int i = 0; i < NazgulEnum.values().length; i++) { - NazgulEnum instance1 = NazgulEnum.values()[i]; - NazgulEnum instance2 = NazgulEnum.values()[i]; - NazgulEnum instance3 = NazgulEnum.values()[i]; + for (var i = 0; i < NazgulEnum.values().length; i++) { + var instance1 = NazgulEnum.values()[i]; + var instance2 = NazgulEnum.values()[i]; + var instance3 = NazgulEnum.values()[i]; assertSame(instance1, instance2); assertSame(instance1, instance3); assertSame(instance2, instance3); diff --git a/multiton/src/test/java/com/iluwatar/multiton/NazgulTest.java b/multiton/src/test/java/com/iluwatar/multiton/NazgulTest.java index 0429f8e29..f900659a8 100644 --- a/multiton/src/test/java/com/iluwatar/multiton/NazgulTest.java +++ b/multiton/src/test/java/com/iluwatar/multiton/NazgulTest.java @@ -41,8 +41,8 @@ public class NazgulTest { */ @Test public void testGetInstance() { - for (final NazgulName name : NazgulName.values()) { - final Nazgul nazgul = Nazgul.getInstance(name); + for (final var name : NazgulName.values()) { + final var nazgul = Nazgul.getInstance(name); assertNotNull(nazgul); assertSame(nazgul, Nazgul.getInstance(name)); assertEquals(name, nazgul.getName()); From 2fa938c02d64edff93757f631fa36fd445624113 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 22:58:50 +0000 Subject: [PATCH 011/285] Java 11 migraiton: mute-idiom --- .../src/main/java/com/iluwatar/mute/App.java | 23 +++++++++---------- .../test/java/com/iluwatar/mute/AppTest.java | 5 ++-- .../test/java/com/iluwatar/mute/MuteTest.java | 18 ++++++--------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/mute-idiom/src/main/java/com/iluwatar/mute/App.java b/mute-idiom/src/main/java/com/iluwatar/mute/App.java index d4f140bf0..eca345014 100644 --- a/mute-idiom/src/main/java/com/iluwatar/mute/App.java +++ b/mute-idiom/src/main/java/com/iluwatar/mute/App.java @@ -25,7 +25,7 @@ package com.iluwatar.mute; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.sql.SQLException; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,9 +52,8 @@ public class App { * Program entry point. * * @param args command line args. - * @throws Exception if any exception occurs */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) { useOfLoggedMute(); @@ -68,17 +67,17 @@ public class App { * exception occurs. */ private static void useOfMute() { - ByteArrayOutputStream out = new ByteArrayOutputStream(); + var out = new ByteArrayOutputStream(); Mute.mute(() -> out.write("Hello".getBytes())); } - private static void useOfLoggedMute() throws SQLException { - Resource resource = null; + private static void useOfLoggedMute() { + Optional resource = Optional.empty(); try { - resource = acquireResource(); - utilizeResource(resource); + resource = Optional.of(acquireResource()); + utilizeResource(resource.get()); } finally { - closeResource(resource); + resource.ifPresent(App::closeResource); } } @@ -86,14 +85,14 @@ public class App { * All we can do while failed close of a resource is to log it. */ private static void closeResource(Resource resource) { - Mute.loggedMute(() -> resource.close()); + Mute.loggedMute(resource::close); } - private static void utilizeResource(Resource resource) throws SQLException { + private static void utilizeResource(Resource resource) { LOGGER.info("Utilizing acquired resource: {}", resource); } - private static Resource acquireResource() throws SQLException { + private static Resource acquireResource() { return new Resource() { @Override diff --git a/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java b/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java index 5ca525a9d..5883812c7 100644 --- a/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java +++ b/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java @@ -27,12 +27,11 @@ import org.junit.jupiter.api.Test; /** * Tests that Mute idiom example runs without errors. - * */ public class AppTest { @Test - public void test() throws Exception { - App.main(null); + public void test() { + App.main(new String[]{}); } } diff --git a/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java b/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java index f2743113b..33d104ffc 100644 --- a/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java +++ b/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java @@ -23,17 +23,15 @@ package com.iluwatar.mute; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; - -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * Test for the mute-idiom pattern */ @@ -50,9 +48,7 @@ public class MuteTest { @Test public void muteShouldRethrowUnexpectedExceptionAsAssertionError() { - assertThrows(AssertionError.class, () -> { - Mute.mute(this::methodThrowingException); - }); + assertThrows(AssertionError.class, () -> Mute.mute(this::methodThrowingException)); } @Test @@ -62,7 +58,7 @@ public class MuteTest { @Test public void loggedMuteShouldLogExceptionTraceBeforeSwallowingIt() { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); + var stream = new ByteArrayOutputStream(); System.setErr(new PrintStream(stream)); Mute.loggedMute(this::methodThrowingException); From d733122e7ac0ee6d169acae38734d6c0a95d6a03 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sun, 12 Apr 2020 23:00:49 +0000 Subject: [PATCH 012/285] Java 11 migraiton: mutex --- mutex/src/main/java/com/iluwatar/mutex/App.java | 8 ++++---- mutex/src/main/java/com/iluwatar/mutex/Jar.java | 2 +- .../src/main/java/com/iluwatar/mutex/Thief.java | 2 +- .../test/java/com/iluwatar/mutex/AppTest.java | 7 ++----- .../test/java/com/iluwatar/mutex/JarTest.java | 17 ++++++++--------- .../test/java/com/iluwatar/mutex/MutexTest.java | 6 +++--- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/mutex/src/main/java/com/iluwatar/mutex/App.java b/mutex/src/main/java/com/iluwatar/mutex/App.java index e4a952ef9..c50acc65a 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/App.java +++ b/mutex/src/main/java/com/iluwatar/mutex/App.java @@ -38,10 +38,10 @@ public class App { * main method. */ public static void main(String[] args) { - Mutex mutex = new Mutex(); - Jar jar = new Jar(1000, mutex); - Thief peter = new Thief("Peter", jar); - Thief john = new Thief("John", jar); + var mutex = new Mutex(); + var jar = new Jar(1000, mutex); + var peter = new Thief("Peter", jar); + var john = new Thief("John", jar); peter.start(); john.start(); } diff --git a/mutex/src/main/java/com/iluwatar/mutex/Jar.java b/mutex/src/main/java/com/iluwatar/mutex/Jar.java index f68b266ad..4a0861e1a 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/Jar.java +++ b/mutex/src/main/java/com/iluwatar/mutex/Jar.java @@ -48,7 +48,7 @@ public class Jar { * Method for a thief to take a bean. */ public boolean takeBean() { - boolean success = false; + var success = false; try { lock.acquire(); success = beans > 0; diff --git a/mutex/src/main/java/com/iluwatar/mutex/Thief.java b/mutex/src/main/java/com/iluwatar/mutex/Thief.java index 29caba540..a9a715970 100644 --- a/mutex/src/main/java/com/iluwatar/mutex/Thief.java +++ b/mutex/src/main/java/com/iluwatar/mutex/Thief.java @@ -54,7 +54,7 @@ public class Thief extends Thread { */ @Override public void run() { - int beans = 0; + var beans = 0; while (jar.takeBean()) { beans = beans + 1; diff --git a/mutex/src/test/java/com/iluwatar/mutex/AppTest.java b/mutex/src/test/java/com/iluwatar/mutex/AppTest.java index 1793bf90b..0bee249a6 100644 --- a/mutex/src/test/java/com/iluwatar/mutex/AppTest.java +++ b/mutex/src/test/java/com/iluwatar/mutex/AppTest.java @@ -25,15 +25,12 @@ package com.iluwatar.mutex; import org.junit.jupiter.api.Test; -import java.io.IOException; - /** * Application Test Entrypoint */ public class AppTest { @Test - public void test() throws IOException { - String[] args = {}; - App.main(args); + public void test() { + App.main(new String[]{}); } } diff --git a/mutex/src/test/java/com/iluwatar/mutex/JarTest.java b/mutex/src/test/java/com/iluwatar/mutex/JarTest.java index e0a316072..786f96e44 100644 --- a/mutex/src/test/java/com/iluwatar/mutex/JarTest.java +++ b/mutex/src/test/java/com/iluwatar/mutex/JarTest.java @@ -23,10 +23,11 @@ package com.iluwatar.mutex; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.stream.IntStream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * Test case for taking beans from a Jar @@ -35,12 +36,10 @@ public class JarTest { @Test public void testTakeBeans() { - Mutex mutex = new Mutex(); - Jar jar = new Jar(10, mutex); - for (int i = 0; i < 10; i++) { - assertTrue(jar.takeBean()); - } + var mutex = new Mutex(); + var jar = new Jar(10, mutex); + IntStream.range(0, 10).mapToObj(i -> jar.takeBean()).forEach(Assertions::assertTrue); assertFalse(jar.takeBean()); } -} \ No newline at end of file +} diff --git a/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java b/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java index 2e3184c51..d6d0cc1d7 100644 --- a/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java +++ b/mutex/src/test/java/com/iluwatar/mutex/MutexTest.java @@ -23,12 +23,12 @@ package com.iluwatar.mutex; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; + /** * Test case for acquiring and releasing a Mutex */ @@ -36,7 +36,7 @@ public class MutexTest { @Test public void acquireReleaseTest() { - Mutex mutex = new Mutex(); + var mutex = new Mutex(); assertNull(mutex.getOwner()); try { mutex.acquire(); From daf53225d8977f2a8998e54e4d5001a3d15a8a03 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Fri, 1 May 2020 08:04:45 +0000 Subject: [PATCH 013/285] Resolves CR comments --- marker/src/main/java/App.java | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/marker/src/main/java/App.java b/marker/src/main/java/App.java index c7b4530c6..8a08a8f70 100644 --- a/marker/src/main/java/App.java +++ b/marker/src/main/java/App.java @@ -21,6 +21,9 @@ * THE SOFTWARE. */ +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Created by Alexis on 28-Apr-17. With Marker interface idea is to make empty interface and extend * it. Basically it is just to identify the special objects from normal objects. Like in case of @@ -43,10 +46,23 @@ public class App { * @param args command line args */ public static void main(String[] args) { + final Logger logger = LoggerFactory.getLogger(App.class); var guard = new Guard(); var thief = new Thief(); - guard.enter(); - thief.doNothing(); + + //noinspection ConstantConditions + if (guard instanceof Permission) { + guard.enter(); + } else { + logger.info("You have no permission to enter, please leave this area"); + } + + //noinspection ConstantConditions + if (thief instanceof Permission) { + thief.doNothing(); + } else { + thief.doNothing(); + } } } From 58b98c54e5cd3a04456e6407745669f9089e9cec Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 15:30:30 +0530 Subject: [PATCH 014/285] #1321 Initial folder setup --- pom.xml | 5 ++++- transaction-script/pom.xml | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 transaction-script/pom.xml diff --git a/pom.xml b/pom.xml index f23369107..017bd7e4a 100644 --- a/pom.xml +++ b/pom.xml @@ -192,6 +192,7 @@ leader-followers strangler arrange-act-assert + transaction-script @@ -377,6 +378,7 @@ maven-surefire-plugin 3.0.0-M3 + -Xmx1024M ${argLine} @@ -474,6 +476,7 @@ true + ${projectRoot}${file.separator}license-plugin-header-style.xml @@ -550,4 +553,4 @@ - \ No newline at end of file + diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml new file mode 100644 index 000000000..1d3c7a8a9 --- /dev/null +++ b/transaction-script/pom.xml @@ -0,0 +1,15 @@ + + + + java-design-patterns + com.iluwatar + 1.23.0-SNAPSHOT + + 4.0.0 + + transaction-script + + + From bf01f3e68b61a8be6830fc48841df0d3f64144b9 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 15:35:53 +0530 Subject: [PATCH 015/285] #1321 Added Readme file --- transaction-script/Readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 transaction-script/Readme.md diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md new file mode 100644 index 000000000..e69de29bb From 58e3fbfc6ab86e9b6fd47618e14e37238cafa638 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 16:19:01 +0530 Subject: [PATCH 016/285] #1321 Added gitignore --- transaction-script/.gitignore | 2 + transaction-script/Readme.md | 49 +++++++++++++++++++ .../transactionscript/App.java | 8 +++ 3 files changed, 59 insertions(+) create mode 100644 transaction-script/.gitignore create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java diff --git a/transaction-script/.gitignore b/transaction-script/.gitignore new file mode 100644 index 000000000..431845ed0 --- /dev/null +++ b/transaction-script/.gitignore @@ -0,0 +1,2 @@ +/target/ +.idea/ diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index e69de29bb..f378e5672 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -0,0 +1,49 @@ +--- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ +layout: pattern # layout must always be pattern +title: Best Pattern Ever # the properly formatted title +folder: best-pattern-ever # the folder name in which this pattern lies +permalink: /patterns/best-pattern-ever/ # the permalink to the pattern, to keep this uniform please stick to /patterns/FOLDER/ +description: # short meta description that shows in Google search results + +# both categories and tags are Yaml Lists +# you can either just pick one or write a list with '-'s +# usable categories and tags are listed here: https://github.com/iluwatar/java-design-patterns/blob/gh-pages/_config.yml +categories: creational # categories of the pattern +tags: # tags of the pattern + - best + - ever + - awesome +--- + +## Name / classification +... + +## Also known as +... + +## Intent +... + +## Explanation +... + +## Class diagram +... + +## Applicability +... + +## Tutorials +... + +## Known uses +... + +## Consequences (the good and the bad, add criticism here) +... + +## Related patterns +... + +## Credits +... diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java new file mode 100644 index 000000000..63aae61b1 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java @@ -0,0 +1,8 @@ +package com.ashishtrivedi16.transactionscript; + +public class App { + + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} From 112973482dc591a7edfba641c58437946ffe5df2 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 16:51:16 +0530 Subject: [PATCH 017/285] #1321 Added basic structure and planned out the roadmap --- .../transactionscript/App.java | 8 ------- .../transactionscript/Hotel.java | 24 +++++++++++++++++++ .../TransactionScriptApp.java | 14 +++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) delete mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java deleted file mode 100644 index 63aae61b1..000000000 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ashishtrivedi16.transactionscript; - -public class App { - - public static void main(String[] args) { - System.out.println("Hello, world!"); - } -} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java new file mode 100644 index 000000000..ec9f8afee --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -0,0 +1,24 @@ +package com.ashishtrivedi16.transactionscript; + +public class Hotel { + + public void bookRoom(int roomNumber) { + /* + TODO + -> Check if room is available + -> Calculate price + -> Book the room + -> Commit transaction + */ + } + + public void cancelRoomBooking(int roomNumber) { + /* + TODO + -> Check if room is booked + -> Calculate refund price + -> Cancel the room booking + -> Commit transaction + */ + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java new file mode 100644 index 000000000..17f8f55f5 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -0,0 +1,14 @@ +package com.ashishtrivedi16.transactionscript; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TransactionScriptApp { + + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + + public static void main(String[] args) { + LOGGER.info("Hello, World!"); + + } +} From 52e6ea2b68a9f7530bf520406225f7e03e544c4b Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 20:33:52 +0530 Subject: [PATCH 018/285] #1321 Implemented DAO --- transaction-script/pom.xml | 13 ++ .../transactionscript/Hotel.java | 19 +-- .../transactionscript/Room.java | 80 ++++++++++ .../TransactionScriptApp.java | 82 +++++++++- .../transactionscript/db/CustomException.java | 43 +++++ .../transactionscript/db/HotelDAO.java | 20 +++ .../transactionscript/db/HotelDAOImpl.java | 151 ++++++++++++++++++ .../transactionscript/db/RoomSchemaSql.java | 39 +++++ 8 files changed, 436 insertions(+), 11 deletions(-) create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index 1d3c7a8a9..3fc06ca51 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -11,5 +11,18 @@ transaction-script + + + com.h2database + h2 + 1.4.200 + test + + + com.h2database + h2 + + + diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index ec9f8afee..d991f0f42 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -4,21 +4,22 @@ public class Hotel { public void bookRoom(int roomNumber) { /* - TODO - -> Check if room is available - -> Calculate price - -> Book the room - -> Commit transaction + TODO + -> Check if room is available + -> Calculate price + -> Book the room + -> Commit transaction */ } public void cancelRoomBooking(int roomNumber) { /* + TODO - -> Check if room is booked - -> Calculate refund price - -> Cancel the room booking - -> Commit transaction + -> Check if room is booked + -> Calculate refund price + -> Cancel the room booking + -> Commit transaction */ } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java new file mode 100644 index 000000000..bf8b1ccf7 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java @@ -0,0 +1,80 @@ +package com.ashishtrivedi16.transactionscript; + +public class Room { + + private int id; + private String roomType; + private int price; + private boolean booked; + + public Room(int id, String roomType, int price, boolean booked) { + this.id = id; + this.roomType = roomType; + this.price = price; + this.booked = booked; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getRoomType() { + return roomType; + } + + public void setRoomType(String roomType) { + this.roomType = roomType; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } + + public boolean isBooked() { + return booked; + } + + public void setBooked(boolean booked) { + this.booked = booked; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Room room = (Room) o; + + if (id != room.id) return false; + if (price != room.price) return false; + if (booked != room.booked) return false; + return roomType == room.roomType; + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + roomType.hashCode(); + result = 31 * result + price; + result = 31 * result + (booked ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "Room{" + + "id=" + id + + ", roomType=" + roomType + + ", price=" + price + + ", booked=" + booked + + '}'; + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index 17f8f55f5..df29c6d09 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -1,14 +1,92 @@ package com.ashishtrivedi16.transactionscript; +import com.ashishtrivedi16.transactionscript.db.HotelDAOImpl; +import com.ashishtrivedi16.transactionscript.db.RoomSchemaSql; +import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.List; + public class TransactionScriptApp { + private static final String H2_DB_URL = "jdbc:h2:~/test"; private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final String ALL_ROOMS = "customerDao.getAllRooms(): "; - public static void main(String[] args) { - LOGGER.info("Hello, World!"); + public static void main(String[] args) throws Exception { + + /* + TODO + -> Create in memory database and some sample tables for demo + */ + final var dataSource = createDataSource(); + createSchema(dataSource); + final var DAO = new HotelDAOImpl(dataSource); + try (var customerStream = DAO.getAll()) { + customerStream.forEach((customer) -> LOGGER.info(customer.toString())); + } + + deleteSchema(dataSource); } + + private static void deleteSchema(DataSource dataSource) throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); + } + } + + private static void createSchema(DataSource dataSource) throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); + } + } + + public static DataSource createDataSource() { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setUrl(H2_DB_URL); + return dataSource; + } + + private static void addRooms(HotelDAOImpl hotelDAO) throws Exception { + for (var room : generateSampleRooms()) { + hotelDAO.add(room); + } + } + + public static List generateSampleRooms() { + final var room1 = new Room(1, "Single", 50, false); + final var room2 = new Room(2, "Double", 80, false); + final var room3 = new Room(3, "Queen", 120, false); + final var room4 = new Room(4, "King", 150, false); + final var room5 = new Room(5, "Single", 50, false); + final var room6 = new Room(6, "Double", 80, false); + return List.of(room1, room2, room3, room4, room5, room6); + } + + private static void generate(final HotelDAOImpl hotelDAO) throws Exception { +// addRooms(hotelDAO); +// LOGGER.info(ALL_ROOMS); +// try (var customerStream = hotelDAO.getAll()) { +// customerStream.forEach((customer) -> LOGGER.info(customer.toString())); +// } +// LOGGER.info("hotelDAO.getCustomerById(2): " + hotelDAO.getById(2)); +// final var customer = new Room(4, "Dan", "Danson"); +// hotelDAO.add(customer); +// LOGGER.info(ALL_ROOMS + hotelDAO.getAll()); +// customer.setFirstName("Daniel"); +// customer.setLastName("Danielson"); +// hotelDAO.update(customer); +// LOGGER.info(ALL_ROOMS); +// try (var customerStream = hotelDAO.getAll()) { +// customerStream.forEach((cust) -> LOGGER.info(cust.toString())); +// } +// hotelDAO.delete(customer); +// LOGGER.info(ALL_ROOMS + hotelDAO.getAll()); + } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java new file mode 100644 index 000000000..4f7e11d45 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java @@ -0,0 +1,43 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript.db; + +/** + * Custom exception. + */ +public class CustomException extends Exception { + + private static final long serialVersionUID = 1L; + + public CustomException() { + } + + public CustomException(String message) { + super(message); + } + + public CustomException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java new file mode 100644 index 000000000..76b577f72 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java @@ -0,0 +1,20 @@ +package com.ashishtrivedi16.transactionscript.db; + +import com.ashishtrivedi16.transactionscript.Room; + +import java.sql.SQLException; +import java.util.Optional; +import java.util.stream.Stream; + +public interface HotelDAO { + + public Stream getAll() throws Exception; + + public Optional getById(int id) throws Exception; + + public Boolean add(Room room) throws SQLException, Exception; + + public Boolean update(Room room) throws Exception; + + public Boolean delete(Room room) throws Exception; +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java new file mode 100644 index 000000000..f4cfcc276 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java @@ -0,0 +1,151 @@ +package com.ashishtrivedi16.transactionscript.db; + +import com.ashishtrivedi16.transactionscript.Room; +import com.ashishtrivedi16.transactionscript.TransactionScriptApp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Optional; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class HotelDAOImpl implements HotelDAO { + + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private final DataSource dataSource; + + public HotelDAOImpl(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Stream getAll() throws Exception { + try { + var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM ROOMS"); + ResultSet resultSet = statement.executeQuery(); // NOSONAR + return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, + Spliterator.ORDERED) { + + @Override + public boolean tryAdvance(Consumer action) { + try { + if (!resultSet.next()) { + return false; + } + action.accept(createRoom(resultSet)); + return true; + } catch (SQLException e) { + throw new RuntimeException(e); // NOSONAR + } + } + }, false).onClose(() -> { + try { + mutedClose(connection, statement, resultSet); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } catch (SQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + @Override + public Optional getById(int id) throws Exception { + ResultSet resultSet = null; + + try (var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM ROOMS WHERE ID = ?")) { + + statement.setInt(1, id); + resultSet = statement.executeQuery(); + if (resultSet.next()) { + return Optional.of(createRoom(resultSet)); + } else { + return Optional.empty(); + } + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } finally { + if (resultSet != null) { + resultSet.close(); + } + } + } + + @Override + public Boolean add(Room room) throws Exception { + if (getById(room.getId()).isPresent()) { + return false; + } + + try (var connection = getConnection(); + var statement = connection.prepareStatement("INSERT INTO ROOMS VALUES (?,?,?)")) { + statement.setInt(1, room.getId()); + statement.setString(2, room.getRoomType()); + statement.setInt(3, room.getPrice()); + statement.setBoolean(4, room.isBooked()); + statement.execute(); + return true; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + @Override + public Boolean update(Room room) throws Exception { + try (var connection = getConnection(); + var statement = + connection + .prepareStatement("UPDATE ROOMS SET ROOM_TYPE = ?, PRICE = ?, BOOKED = ? WHERE ID = ?")) { + statement.setInt(1, room.getId()); + statement.setString(2, room.getRoomType()); + statement.setBoolean(3, room.isBooked()); + statement.setInt(4, room.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + @Override + public Boolean delete(Room room) throws Exception { + try (var connection = getConnection(); + var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + statement.setInt(1, room.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + private Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + private void mutedClose(Connection connection, PreparedStatement statement, ResultSet resultSet) throws Exception { + try { + resultSet.close(); + statement.close(); + connection.close(); + } catch (SQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + private Room createRoom(ResultSet resultSet) throws SQLException { + return new Room(resultSet.getInt("ID"), + resultSet.getString("ROOM_TYPE"), + resultSet.getInt("PRICE"), + resultSet.getBoolean("BOOKED")); + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java new file mode 100644 index 000000000..e883e50b9 --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java @@ -0,0 +1,39 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript.db; + +/** + * Customer Schema SQL Class. + */ +public final class RoomSchemaSql { + + private RoomSchemaSql() { + } + + public static final String CREATE_SCHEMA_SQL = + "CREATE TABLE ROOMS (ID NUMBER, ROOM_TYPE VARCHAR(100), PRICE INT(100), BOOKED VARCHAR(100))"; + + public static final String DELETE_SCHEMA_SQL = "DROP TABLE ROOMS"; + +} From c4b1b89f1ff3ad15d06dfad9a0e0575c22ae032f Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 19 Jul 2020 22:20:15 +0530 Subject: [PATCH 019/285] #1321 --- .../transactionscript/Hotel.java | 32 ++++++++++-- .../TransactionScriptApp.java | 50 +++++++++---------- .../transactionscript/db/HotelDAO.java | 3 +- .../transactionscript/db/HotelDAOImpl.java | 6 +-- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index d991f0f42..17a9512a9 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -1,15 +1,41 @@ package com.ashishtrivedi16.transactionscript; -public class Hotel { +import com.ashishtrivedi16.transactionscript.db.HotelDAOImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; - public void bookRoom(int roomNumber) { +import java.util.Optional; + +public class Hotel { + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + + private HotelDAOImpl hotelDAO; + + public Hotel(HotelDAOImpl hotelDAO) { + this.hotelDAO = hotelDAO; + } + + public void bookRoom(int roomNumber) throws Exception { /* TODO -> Check if room is available - -> Calculate price -> Book the room -> Commit transaction */ + + Optional room = hotelDAO.getById(roomNumber); + + if (!room.isPresent()) { + LOGGER.info(roomNumber + " does not exist"); + } else { + if (room.get().isBooked()) { + LOGGER.info("Room already booked!"); + } else { + Room updateRoomBooking = room.get(); + updateRoomBooking.setBooked(true); + hotelDAO.update(updateRoomBooking); + } + } } public void cancelRoomBooking(int roomNumber) { diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index df29c6d09..d218da078 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -1,15 +1,18 @@ package com.ashishtrivedi16.transactionscript; +import com.ashishtrivedi16.transactionscript.db.CustomException; import com.ashishtrivedi16.transactionscript.db.HotelDAOImpl; import com.ashishtrivedi16.transactionscript.db.RoomSchemaSql; + +import java.sql.SQLException; +import java.util.List; +import javax.sql.DataSource; + +import org.h2.jdbc.JdbcSQLException; import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.sql.DataSource; -import java.sql.SQLException; -import java.util.List; - public class TransactionScriptApp { private static final String H2_DB_URL = "jdbc:h2:~/test"; @@ -25,10 +28,24 @@ public class TransactionScriptApp { final var dataSource = createDataSource(); createSchema(dataSource); final var DAO = new HotelDAOImpl(dataSource); + + addRooms(DAO); try (var customerStream = DAO.getAll()) { customerStream.forEach((customer) -> LOGGER.info(customer.toString())); } + Hotel hotel = new Hotel(DAO); + + hotel.bookRoom(1); + hotel.bookRoom(2); + hotel.bookRoom(3); + hotel.bookRoom(4); + hotel.bookRoom(5); + hotel.bookRoom(6); + + hotel.cancelRoomBooking(3); + hotel.cancelRoomBooking(4); + deleteSchema(dataSource); } @@ -40,10 +57,12 @@ public class TransactionScriptApp { } } - private static void createSchema(DataSource dataSource) throws SQLException { + private static void createSchema(DataSource dataSource) throws Exception { try (var connection = dataSource.getConnection(); var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); + } catch (JdbcSQLException e) { + throw new CustomException(e.getMessage(), e); } } @@ -68,25 +87,4 @@ public class TransactionScriptApp { final var room6 = new Room(6, "Double", 80, false); return List.of(room1, room2, room3, room4, room5, room6); } - - private static void generate(final HotelDAOImpl hotelDAO) throws Exception { -// addRooms(hotelDAO); -// LOGGER.info(ALL_ROOMS); -// try (var customerStream = hotelDAO.getAll()) { -// customerStream.forEach((customer) -> LOGGER.info(customer.toString())); -// } -// LOGGER.info("hotelDAO.getCustomerById(2): " + hotelDAO.getById(2)); -// final var customer = new Room(4, "Dan", "Danson"); -// hotelDAO.add(customer); -// LOGGER.info(ALL_ROOMS + hotelDAO.getAll()); -// customer.setFirstName("Daniel"); -// customer.setLastName("Danielson"); -// hotelDAO.update(customer); -// LOGGER.info(ALL_ROOMS); -// try (var customerStream = hotelDAO.getAll()) { -// customerStream.forEach((cust) -> LOGGER.info(cust.toString())); -// } -// hotelDAO.delete(customer); -// LOGGER.info(ALL_ROOMS + hotelDAO.getAll()); - } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java index 76b577f72..d7a763862 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java @@ -2,7 +2,6 @@ package com.ashishtrivedi16.transactionscript.db; import com.ashishtrivedi16.transactionscript.Room; -import java.sql.SQLException; import java.util.Optional; import java.util.stream.Stream; @@ -12,7 +11,7 @@ public interface HotelDAO { public Optional getById(int id) throws Exception; - public Boolean add(Room room) throws SQLException, Exception; + public Boolean add(Room room) throws Exception; public Boolean update(Room room) throws Exception; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java index f4cfcc276..c4a18633c 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java @@ -1,9 +1,6 @@ package com.ashishtrivedi16.transactionscript.db; import com.ashishtrivedi16.transactionscript.Room; -import com.ashishtrivedi16.transactionscript.TransactionScriptApp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.sql.DataSource; import java.sql.Connection; @@ -19,7 +16,6 @@ import java.util.stream.StreamSupport; public class HotelDAOImpl implements HotelDAO { - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); private final DataSource dataSource; public HotelDAOImpl(DataSource dataSource) { @@ -89,7 +85,7 @@ public class HotelDAOImpl implements HotelDAO { } try (var connection = getConnection(); - var statement = connection.prepareStatement("INSERT INTO ROOMS VALUES (?,?,?)")) { + var statement = connection.prepareStatement("INSERT INTO ROOMS VALUES (?,?,?,?)")) { statement.setInt(1, room.getId()); statement.setString(2, room.getRoomType()); statement.setInt(3, room.getPrice()); From e0fb2d014ab5ed90e30766d37322dbf84ccbdc96 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 26 Jul 2020 15:56:55 +0530 Subject: [PATCH 020/285] #1321 Added comments and refactored code --- .../{com/iluwatar/dao => }/module-info.java | 0 transaction-script/pom.xml | 10 +- .../transactionscript/Hotel.java | 89 +++++----- .../transactionscript/Room.java | 154 ++++++++++-------- .../TransactionScriptApp.java | 134 ++++++++------- .../transactionscript/db/HotelDAO.java | 19 --- .../transactionscript/db/HotelDAOImpl.java | 147 ----------------- .../transactionscript/db/HotelDao.java | 19 +++ .../transactionscript/db/HotelDaoImpl.java | 148 +++++++++++++++++ .../transactionscript/db/RoomSchemaSql.java | 9 +- 10 files changed, 391 insertions(+), 338 deletions(-) rename dao/src/main/java/{com/iluwatar/dao => }/module-info.java (100%) delete mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java delete mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java create mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java diff --git a/dao/src/main/java/com/iluwatar/dao/module-info.java b/dao/src/main/java/module-info.java similarity index 100% rename from dao/src/main/java/com/iluwatar/dao/module-info.java rename to dao/src/main/java/module-info.java diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index 3fc06ca51..bf2811994 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -1,6 +1,6 @@ - java-design-patterns @@ -15,14 +15,14 @@ com.h2database h2 - 1.4.200 - test + com.h2database h2 + 1.4.200 + test - diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index 17a9512a9..c459c32d5 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -1,51 +1,66 @@ package com.ashishtrivedi16.transactionscript; -import com.ashishtrivedi16.transactionscript.db.HotelDAOImpl; +import com.ashishtrivedi16.transactionscript.db.HotelDaoImpl; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Optional; - public class Hotel { - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); - private HotelDAOImpl hotelDAO; + private HotelDaoImpl hotelDao; - public Hotel(HotelDAOImpl hotelDAO) { - this.hotelDAO = hotelDAO; + public Hotel(HotelDaoImpl hotelDao) { + this.hotelDao = hotelDao; + } + + /** + * Book a room. + * + * @param roomNumber room to book + * @throws Exception if any error + */ + public void bookRoom(int roomNumber) throws Exception { + + Optional room = hotelDao.getById(roomNumber); + + if (room.isEmpty()) { + LOGGER.info(roomNumber + " does not exist"); + } else { + if (room.get().isBooked()) { + LOGGER.info("Room already booked!"); + } else { + Room updateRoomBooking = room.get(); + updateRoomBooking.setBooked(true); + hotelDao.update(updateRoomBooking); + } } + } - public void bookRoom(int roomNumber) throws Exception { - /* - TODO - -> Check if room is available - -> Book the room - -> Commit transaction - */ + /** + * Cancel a room booking. + * + * @param roomNumber room to cancel booking + * @throws Exception if any error + */ + public void cancelRoomBooking(int roomNumber) throws Exception { - Optional room = hotelDAO.getById(roomNumber); + Optional room = hotelDao.getById(roomNumber); - if (!room.isPresent()) { - LOGGER.info(roomNumber + " does not exist"); - } else { - if (room.get().isBooked()) { - LOGGER.info("Room already booked!"); - } else { - Room updateRoomBooking = room.get(); - updateRoomBooking.setBooked(true); - hotelDAO.update(updateRoomBooking); - } - } - } - - public void cancelRoomBooking(int roomNumber) { - /* - - TODO - -> Check if room is booked - -> Calculate refund price - -> Cancel the room booking - -> Commit transaction - */ + if (room.isEmpty()) { + LOGGER.info("Room number: " + roomNumber + " does not exist"); + } else { + if (room.get().isBooked()) { + Room updateRoomBooking = room.get(); + updateRoomBooking.setBooked(false); + int refundAmount = updateRoomBooking.getPrice(); + hotelDao.update(updateRoomBooking); + + LOGGER.info("Booking cancelled for room number: " + roomNumber); + LOGGER.info(refundAmount + " is refunded"); + } else { + LOGGER.info("No booking for the room exists"); + } } + } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java index bf8b1ccf7..55a93ddec 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java @@ -1,80 +1,100 @@ package com.ashishtrivedi16.transactionscript; +/** + * A room POJO that represents the data that will be read from the data source. + */ public class Room { - private int id; - private String roomType; - private int price; - private boolean booked; + private int id; + private String roomType; + private int price; + private boolean booked; - public Room(int id, String roomType, int price, boolean booked) { - this.id = id; - this.roomType = roomType; - this.price = price; - this.booked = booked; + /** + * Create an instance of room. + * @param id room id + * @param roomType room type + * @param price room price + * @param booked room booking status + */ + public Room(int id, String roomType, int price, boolean booked) { + this.id = id; + this.roomType = roomType; + this.price = price; + this.booked = booked; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getRoomType() { + return roomType; + } + + public void setRoomType(String roomType) { + this.roomType = roomType; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } + + public boolean isBooked() { + return booked; + } + + public void setBooked(boolean booked) { + this.booked = booked; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } - public int getId() { - return id; + Room room = (Room) o; + + if (id != room.id) { + return false; } - - public void setId(int id) { - this.id = id; + if (price != room.price) { + return false; } - - public String getRoomType() { - return roomType; + if (booked != room.booked) { + return false; } + return roomType.equals(room.roomType); + } - public void setRoomType(String roomType) { - this.roomType = roomType; - } + @Override + public int hashCode() { + int result = id; + result = 31 * result + roomType.hashCode(); + result = 31 * result + price; + result = 31 * result + (booked ? 1 : 0); + return result; + } - public int getPrice() { - return price; - } - - public void setPrice(int price) { - this.price = price; - } - - public boolean isBooked() { - return booked; - } - - public void setBooked(boolean booked) { - this.booked = booked; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Room room = (Room) o; - - if (id != room.id) return false; - if (price != room.price) return false; - if (booked != room.booked) return false; - return roomType == room.roomType; - } - - @Override - public int hashCode() { - int result = id; - result = 31 * result + roomType.hashCode(); - result = 31 * result + price; - result = 31 * result + (booked ? 1 : 0); - return result; - } - - @Override - public String toString() { - return "Room{" + - "id=" + id + - ", roomType=" + roomType + - ", price=" + price + - ", booked=" + booked + - '}'; - } + @Override + public String toString() { + return "Room{" + + "id=" + id + + ", roomType=" + roomType + + ", price=" + price + + ", booked=" + booked + + '}'; + } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index d218da078..c04306a18 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -1,13 +1,11 @@ package com.ashishtrivedi16.transactionscript; import com.ashishtrivedi16.transactionscript.db.CustomException; -import com.ashishtrivedi16.transactionscript.db.HotelDAOImpl; +import com.ashishtrivedi16.transactionscript.db.HotelDaoImpl; import com.ashishtrivedi16.transactionscript.db.RoomSchemaSql; - import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; - import org.h2.jdbc.JdbcSQLException; import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; @@ -15,76 +13,96 @@ import org.slf4j.LoggerFactory; public class TransactionScriptApp { - private static final String H2_DB_URL = "jdbc:h2:~/test"; - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); - private static final String ALL_ROOMS = "customerDao.getAllRooms(): "; + private static final String H2_DB_URL = "jdbc:h2:~/test"; + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final String ALL_ROOMS = "customerDao.getAllRooms(): "; - public static void main(String[] args) throws Exception { + /** + * Program entry point. + * + * @param args command line arguments + * @throws Exception if any error occurs + */ + public static void main(String[] args) throws Exception { - /* - TODO - -> Create in memory database and some sample tables for demo - */ - final var dataSource = createDataSource(); - createSchema(dataSource); - final var DAO = new HotelDAOImpl(dataSource); + final var dataSource = createDataSource(); + deleteSchema(dataSource); + createSchema(dataSource); + final var dao = new HotelDaoImpl(dataSource); + addRooms(dao); - addRooms(DAO); - try (var customerStream = DAO.getAll()) { - customerStream.forEach((customer) -> LOGGER.info(customer.toString())); - } + getRoomStatus(dao); - Hotel hotel = new Hotel(DAO); + Hotel hotel = new Hotel(dao); - hotel.bookRoom(1); - hotel.bookRoom(2); - hotel.bookRoom(3); - hotel.bookRoom(4); - hotel.bookRoom(5); - hotel.bookRoom(6); + hotel.bookRoom(1); + hotel.bookRoom(2); + hotel.bookRoom(3); + hotel.bookRoom(4); + hotel.bookRoom(5); + hotel.bookRoom(6); - hotel.cancelRoomBooking(3); - hotel.cancelRoomBooking(4); + hotel.cancelRoomBooking(1); + hotel.cancelRoomBooking(3); + hotel.cancelRoomBooking(5); - deleteSchema(dataSource); + getRoomStatus(dao); + deleteSchema(dataSource); + + } + + private static void getRoomStatus(HotelDaoImpl dao) throws Exception { + try (var customerStream = dao.getAll()) { + customerStream.forEach((customer) -> LOGGER.info(customer.toString())); } + } - private static void deleteSchema(DataSource dataSource) throws SQLException { - try (var connection = dataSource.getConnection(); - var statement = connection.createStatement()) { - statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); - } + private static void deleteSchema(DataSource dataSource) throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); } + } - private static void createSchema(DataSource dataSource) throws Exception { - try (var connection = dataSource.getConnection(); - var statement = connection.createStatement()) { - statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); - } catch (JdbcSQLException e) { - throw new CustomException(e.getMessage(), e); - } + private static void createSchema(DataSource dataSource) throws Exception { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); + } catch (JdbcSQLException e) { + throw new CustomException(e.getMessage(), e); } + } - public static DataSource createDataSource() { - JdbcDataSource dataSource = new JdbcDataSource(); - dataSource.setUrl(H2_DB_URL); - return dataSource; - } + /** + * Get database. + * + * @return h2 datasource + */ + public static DataSource createDataSource() { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setUrl(H2_DB_URL); + return dataSource; + } - private static void addRooms(HotelDAOImpl hotelDAO) throws Exception { - for (var room : generateSampleRooms()) { - hotelDAO.add(room); - } + private static void addRooms(HotelDaoImpl hotelDao) throws Exception { + for (var room : generateSampleRooms()) { + hotelDao.add(room); } + } - public static List generateSampleRooms() { - final var room1 = new Room(1, "Single", 50, false); - final var room2 = new Room(2, "Double", 80, false); - final var room3 = new Room(3, "Queen", 120, false); - final var room4 = new Room(4, "King", 150, false); - final var room5 = new Room(5, "Single", 50, false); - final var room6 = new Room(6, "Double", 80, false); - return List.of(room1, room2, room3, room4, room5, room6); - } + /** + * Generate rooms. + * + * @return list of rooms + */ + public static List generateSampleRooms() { + final var room1 = new Room(1, "Single", 50, false); + final var room2 = new Room(2, "Double", 80, false); + final var room3 = new Room(3, "Queen", 120, false); + final var room4 = new Room(4, "King", 150, false); + final var room5 = new Room(5, "Single", 50, false); + final var room6 = new Room(6, "Double", 80, false); + return List.of(room1, room2, room3, room4, room5, room6); + } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java deleted file mode 100644 index d7a763862..000000000 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAO.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.ashishtrivedi16.transactionscript.db; - -import com.ashishtrivedi16.transactionscript.Room; - -import java.util.Optional; -import java.util.stream.Stream; - -public interface HotelDAO { - - public Stream getAll() throws Exception; - - public Optional getById(int id) throws Exception; - - public Boolean add(Room room) throws Exception; - - public Boolean update(Room room) throws Exception; - - public Boolean delete(Room room) throws Exception; -} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java deleted file mode 100644 index c4a18633c..000000000 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDAOImpl.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.ashishtrivedi16.transactionscript.db; - -import com.ashishtrivedi16.transactionscript.Room; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Optional; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.Consumer; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -public class HotelDAOImpl implements HotelDAO { - - private final DataSource dataSource; - - public HotelDAOImpl(DataSource dataSource) { - this.dataSource = dataSource; - } - - @Override - public Stream getAll() throws Exception { - try { - var connection = getConnection(); - var statement = connection.prepareStatement("SELECT * FROM ROOMS"); - ResultSet resultSet = statement.executeQuery(); // NOSONAR - return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, - Spliterator.ORDERED) { - - @Override - public boolean tryAdvance(Consumer action) { - try { - if (!resultSet.next()) { - return false; - } - action.accept(createRoom(resultSet)); - return true; - } catch (SQLException e) { - throw new RuntimeException(e); // NOSONAR - } - } - }, false).onClose(() -> { - try { - mutedClose(connection, statement, resultSet); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } catch (SQLException e) { - throw new CustomException(e.getMessage(), e); - } - } - - @Override - public Optional getById(int id) throws Exception { - ResultSet resultSet = null; - - try (var connection = getConnection(); - var statement = connection.prepareStatement("SELECT * FROM ROOMS WHERE ID = ?")) { - - statement.setInt(1, id); - resultSet = statement.executeQuery(); - if (resultSet.next()) { - return Optional.of(createRoom(resultSet)); - } else { - return Optional.empty(); - } - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); - } finally { - if (resultSet != null) { - resultSet.close(); - } - } - } - - @Override - public Boolean add(Room room) throws Exception { - if (getById(room.getId()).isPresent()) { - return false; - } - - try (var connection = getConnection(); - var statement = connection.prepareStatement("INSERT INTO ROOMS VALUES (?,?,?,?)")) { - statement.setInt(1, room.getId()); - statement.setString(2, room.getRoomType()); - statement.setInt(3, room.getPrice()); - statement.setBoolean(4, room.isBooked()); - statement.execute(); - return true; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); - } - } - - @Override - public Boolean update(Room room) throws Exception { - try (var connection = getConnection(); - var statement = - connection - .prepareStatement("UPDATE ROOMS SET ROOM_TYPE = ?, PRICE = ?, BOOKED = ? WHERE ID = ?")) { - statement.setInt(1, room.getId()); - statement.setString(2, room.getRoomType()); - statement.setBoolean(3, room.isBooked()); - statement.setInt(4, room.getId()); - return statement.executeUpdate() > 0; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); - } - } - - @Override - public Boolean delete(Room room) throws Exception { - try (var connection = getConnection(); - var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { - statement.setInt(1, room.getId()); - return statement.executeUpdate() > 0; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); - } - } - - private Connection getConnection() throws SQLException { - return dataSource.getConnection(); - } - - private void mutedClose(Connection connection, PreparedStatement statement, ResultSet resultSet) throws Exception { - try { - resultSet.close(); - statement.close(); - connection.close(); - } catch (SQLException e) { - throw new CustomException(e.getMessage(), e); - } - } - - private Room createRoom(ResultSet resultSet) throws SQLException { - return new Room(resultSet.getInt("ID"), - resultSet.getString("ROOM_TYPE"), - resultSet.getInt("PRICE"), - resultSet.getBoolean("BOOKED")); - } -} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java new file mode 100644 index 000000000..ee2b6de7e --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java @@ -0,0 +1,19 @@ +package com.ashishtrivedi16.transactionscript.db; + +import com.ashishtrivedi16.transactionscript.Room; + +import java.util.Optional; +import java.util.stream.Stream; + +public interface HotelDao { + + Stream getAll() throws Exception; + + Optional getById(int id) throws Exception; + + Boolean add(Room room) throws Exception; + + Boolean update(Room room) throws Exception; + + Boolean delete(Room room) throws Exception; +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java new file mode 100644 index 000000000..4124a4bcf --- /dev/null +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java @@ -0,0 +1,148 @@ +package com.ashishtrivedi16.transactionscript.db; + +import com.ashishtrivedi16.transactionscript.Room; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Optional; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import javax.sql.DataSource; + +public class HotelDaoImpl implements HotelDao { + + private final DataSource dataSource; + + public HotelDaoImpl(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Stream getAll() throws Exception { + try { + var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM ROOMS"); + ResultSet resultSet = statement.executeQuery(); // NOSONAR + return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, + Spliterator.ORDERED) { + + @Override + public boolean tryAdvance(Consumer action) { + try { + if (!resultSet.next()) { + return false; + } + action.accept(createRoom(resultSet)); + return true; + } catch (SQLException e) { + throw new RuntimeException(e); // NOSONAR + } + } + }, false).onClose(() -> { + try { + mutedClose(connection, statement, resultSet); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } catch (SQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + @Override + public Optional getById(int id) throws Exception { + ResultSet resultSet = null; + + try (var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM ROOMS WHERE ID = ?")) { + + statement.setInt(1, id); + resultSet = statement.executeQuery(); + if (resultSet.next()) { + return Optional.of(createRoom(resultSet)); + } else { + return Optional.empty(); + } + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } finally { + if (resultSet != null) { + resultSet.close(); + } + } + } + + @Override + public Boolean add(Room room) throws Exception { + if (getById(room.getId()).isPresent()) { + return false; + } + + try (var connection = getConnection(); + var statement = connection.prepareStatement("INSERT INTO ROOMS VALUES (?,?,?,?)")) { + statement.setInt(1, room.getId()); + statement.setString(2, room.getRoomType()); + statement.setInt(3, room.getPrice()); + statement.setBoolean(4, room.isBooked()); + statement.execute(); + return true; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + @Override + public Boolean update(Room room) throws Exception { + try (var connection = getConnection(); + var statement = + connection + .prepareStatement("UPDATE ROOMS SET ROOM_TYPE = ?, PRICE = ?, BOOKED = ?" + + " WHERE ID = ?")) { + statement.setString(1, room.getRoomType()); + statement.setInt(2, room.getPrice()); + statement.setBoolean(3, room.isBooked()); + statement.setInt(4, room.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + @Override + public Boolean delete(Room room) throws Exception { + try (var connection = getConnection(); + var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + statement.setInt(1, room.getId()); + return statement.executeUpdate() > 0; + } catch (SQLException ex) { + throw new CustomException(ex.getMessage(), ex); + } + } + + private Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + private void mutedClose(Connection connection, PreparedStatement statement, ResultSet resultSet) + throws Exception { + try { + resultSet.close(); + statement.close(); + connection.close(); + } catch (SQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + private Room createRoom(ResultSet resultSet) throws SQLException { + return new Room(resultSet.getInt("ID"), + resultSet.getString("ROOM_TYPE"), + resultSet.getInt("PRICE"), + resultSet.getBoolean("BOOKED")); + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java index e883e50b9..3ac8fed06 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java @@ -28,12 +28,11 @@ package com.ashishtrivedi16.transactionscript.db; */ public final class RoomSchemaSql { + public static final String CREATE_SCHEMA_SQL = + "CREATE TABLE ROOMS (ID NUMBER, ROOM_TYPE VARCHAR(100), PRICE INT(100), BOOKED VARCHAR(100))"; + public static final String DELETE_SCHEMA_SQL = "DROP TABLE ROOMS IF EXISTS"; + private RoomSchemaSql() { } - public static final String CREATE_SCHEMA_SQL = - "CREATE TABLE ROOMS (ID NUMBER, ROOM_TYPE VARCHAR(100), PRICE INT(100), BOOKED VARCHAR(100))"; - - public static final String DELETE_SCHEMA_SQL = "DROP TABLE ROOMS"; - } From 75ab3b52457c4f481706af9d921af3eea720fee6 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 26 Jul 2020 17:38:33 +0530 Subject: [PATCH 021/285] #1321 Added Tests --- transaction-script/pom.xml | 34 ++- .../{db => }/CustomException.java | 86 +++--- .../transactionscript/Hotel.java | 9 +- .../transactionscript/{db => }/HotelDao.java | 4 +- .../{db => }/HotelDaoImpl.java | 5 +- .../{db => }/RoomSchemaSql.java | 2 +- .../TransactionScriptApp.java | 4 - .../transactionscript/AppTest.java | 36 +++ .../transactionscript/HotelDaoImplTest.java | 272 ++++++++++++++++++ .../transactionscript/HotelTest.java | 123 ++++++++ .../transactionscript/RoomTest.java | 95 ++++++ 11 files changed, 610 insertions(+), 60 deletions(-) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{db => }/CustomException.java (94%) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{db => }/HotelDao.java (76%) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{db => }/HotelDaoImpl.java (97%) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{db => }/RoomSchemaSql.java (96%) create mode 100644 transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java create mode 100644 transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java create mode 100644 transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java create mode 100644 transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index bf2811994..64e824ead 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -16,13 +16,45 @@ com.h2database h2 - com.h2database h2 1.4.200 test + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-core + + + com.h2database + h2 + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.ashishtrivedi16.transactionscript.TransactionScriptApp + + + + + + + + + diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java similarity index 94% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java index 4f7e11d45..002ea79aa 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/CustomException.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java @@ -1,43 +1,43 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript.db; - -/** - * Custom exception. - */ -public class CustomException extends Exception { - - private static final long serialVersionUID = 1L; - - public CustomException() { - } - - public CustomException(String message) { - super(message); - } - - public CustomException(String message, Throwable cause) { - super(message, cause); - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; + +/** + * Custom exception. + */ +public class CustomException extends Exception { + + private static final long serialVersionUID = 1L; + + public CustomException() { + } + + public CustomException(String message) { + super(message); + } + + public CustomException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index c459c32d5..212a0df68 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -1,6 +1,5 @@ package com.ashishtrivedi16.transactionscript; -import com.ashishtrivedi16.transactionscript.db.HotelDaoImpl; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,10 +24,10 @@ public class Hotel { Optional room = hotelDao.getById(roomNumber); if (room.isEmpty()) { - LOGGER.info(roomNumber + " does not exist"); + throw new Exception("Room number: " + roomNumber + " does not exist"); } else { if (room.get().isBooked()) { - LOGGER.info("Room already booked!"); + throw new Exception("Room already booked!"); } else { Room updateRoomBooking = room.get(); updateRoomBooking.setBooked(true); @@ -48,7 +47,7 @@ public class Hotel { Optional room = hotelDao.getById(roomNumber); if (room.isEmpty()) { - LOGGER.info("Room number: " + roomNumber + " does not exist"); + throw new Exception("Room number: " + roomNumber + " does not exist"); } else { if (room.get().isBooked()) { Room updateRoomBooking = room.get(); @@ -59,7 +58,7 @@ public class Hotel { LOGGER.info("Booking cancelled for room number: " + roomNumber); LOGGER.info(refundAmount + " is refunded"); } else { - LOGGER.info("No booking for the room exists"); + throw new Exception("No booking for the room exists"); } } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java similarity index 76% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java index ee2b6de7e..7efa3c9e6 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDao.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java @@ -1,6 +1,4 @@ -package com.ashishtrivedi16.transactionscript.db; - -import com.ashishtrivedi16.transactionscript.Room; +package com.ashishtrivedi16.transactionscript; import java.util.Optional; import java.util.stream.Stream; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java similarity index 97% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java index 4124a4bcf..88e7984a6 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java @@ -1,6 +1,5 @@ -package com.ashishtrivedi16.transactionscript.db; +package com.ashishtrivedi16.transactionscript; -import com.ashishtrivedi16.transactionscript.Room; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -116,7 +115,7 @@ public class HotelDaoImpl implements HotelDao { @Override public Boolean delete(Room room) throws Exception { try (var connection = getConnection(); - var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + var statement = connection.prepareStatement("DELETE FROM ROOMS WHERE ID = ?")) { statement.setInt(1, room.getId()); return statement.executeUpdate() > 0; } catch (SQLException ex) { diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java similarity index 96% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java index 3ac8fed06..bb2e2374b 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/db/RoomSchemaSql.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript.db; +package com.ashishtrivedi16.transactionscript; /** * Customer Schema SQL Class. diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index c04306a18..dfd980b46 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -1,8 +1,5 @@ package com.ashishtrivedi16.transactionscript; -import com.ashishtrivedi16.transactionscript.db.CustomException; -import com.ashishtrivedi16.transactionscript.db.HotelDaoImpl; -import com.ashishtrivedi16.transactionscript.db.RoomSchemaSql; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; @@ -15,7 +12,6 @@ public class TransactionScriptApp { private static final String H2_DB_URL = "jdbc:h2:~/test"; private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); - private static final String ALL_ROOMS = "customerDao.getAllRooms(): "; /** * Program entry point. diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java new file mode 100644 index 000000000..a4c22739d --- /dev/null +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java @@ -0,0 +1,36 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; + +import org.junit.jupiter.api.Test; + +/** + * Tests that Transaction script example runs without errors. + */ +public class AppTest { + @Test + public void test() throws Exception { + TransactionScriptApp.main(new String[]{}); + } +} diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java new file mode 100644 index 000000000..01c588075 --- /dev/null +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java @@ -0,0 +1,272 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; + +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.Mockito.*; + +/** + * Tests {@link HotelDaoImpl}. + */ +public class HotelDaoImplTest { + + private static final String DB_URL = "jdbc:h2:~/test"; + private HotelDaoImpl dao; + private Room existingRoom = new Room(1, "Single", 50, false); + + /** + * Creates rooms schema. + * + * @throws SQLException if there is any error while creating schema. + */ + @BeforeEach + public void createSchema() throws SQLException { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); + } + } + + /** + * Represents the scenario where DB connectivity is present. + */ + @Nested + public class ConnectionSuccess { + + /** + * Setup for connection success scenario. + * + * @throws Exception if any error occurs. + */ + @BeforeEach + public void setUp() throws Exception { + var dataSource = new JdbcDataSource(); + dataSource.setURL(DB_URL); + dao = new HotelDaoImpl(dataSource); + var result = dao.add(existingRoom); + assertTrue(result); + } + + /** + * Represents the scenario when DAO operations are being performed on a non existing room. + */ + @Nested + public class NonExistingRoom { + + @Test + public void addingShouldResultInSuccess() throws Exception { + try (var allRooms = dao.getAll()) { + assumeTrue(allRooms.count() == 1); + } + + final var nonExistingRoom = new Room(2, "Double", 80, false); + var result = dao.add(nonExistingRoom); + assertTrue(result); + + assertRoomCountIs(2); + assertEquals(nonExistingRoom, dao.getById(nonExistingRoom.getId()).get()); + } + + @Test + public void deletionShouldBeFailureAndNotAffectExistingRooms() throws Exception { + final var nonExistingRoom = new Room(2, "Double", 80, false); + var result = dao.delete(nonExistingRoom); + + assertFalse(result); + assertRoomCountIs(1); + } + + @Test + public void updationShouldBeFailureAndNotAffectExistingRooms() throws Exception { + final var nonExistingId = getNonExistingRoomId(); + final var newRoomType = "Double"; + final var newPrice = 80; + final var room = new Room(nonExistingId, newRoomType, newPrice, false); + var result = dao.update(room); + + assertFalse(result); + assertFalse(dao.getById(nonExistingId).isPresent()); + } + + @Test + public void retrieveShouldReturnNoRoom() throws Exception { + assertFalse(dao.getById(getNonExistingRoomId()).isPresent()); + } + } + + /** + * Represents a scenario where DAO operations are being performed on an already existing + * room. + */ + @Nested + public class ExistingRoom { + + @Test + public void addingShouldResultInFailureAndNotAffectExistingRooms() throws Exception { + var existingRoom = new Room(1, "Single", 50, false); + var result = dao.add(existingRoom); + + assertFalse(result); + assertRoomCountIs(1); + assertEquals(existingRoom, dao.getById(existingRoom.getId()).get()); + } + + @Test + public void deletionShouldBeSuccessAndRoomShouldBeNonAccessible() throws Exception { + var result = dao.delete(existingRoom); + + assertTrue(result); + assertRoomCountIs(0); + assertFalse(dao.getById(existingRoom.getId()).isPresent()); + } + + @Test + public void updationShouldBeSuccessAndAccessingTheSameRoomShouldReturnUpdatedInformation() throws + Exception { + final var newRoomType = "Double"; + final var newPrice = 80; + final var newBookingStatus = false; + final var Room = new Room(existingRoom.getId(), newRoomType, newPrice, newBookingStatus); + var result = dao.update(Room); + + assertTrue(result); + + final var room = dao.getById(existingRoom.getId()).get(); + assertEquals(newRoomType, room.getRoomType()); + assertEquals(newPrice, room.getPrice()); + assertEquals(newBookingStatus, room.isBooked()); + } + } + } + + /** + * Represents a scenario where DB connectivity is not present due to network issue, or DB service + * unavailable. + */ + @Nested + public class ConnectivityIssue { + + private static final String EXCEPTION_CAUSE = "Connection not available"; + + /** + * setup a connection failure scenario. + * + * @throws SQLException if any error occurs. + */ + @BeforeEach + public void setUp() throws SQLException { + dao = new HotelDaoImpl(mockedDatasource()); + } + + private DataSource mockedDatasource() throws SQLException { + var mockedDataSource = mock(DataSource.class); + var mockedConnection = mock(Connection.class); + var exception = new SQLException(EXCEPTION_CAUSE); + doThrow(exception).when(mockedConnection).prepareStatement(Mockito.anyString()); + doReturn(mockedConnection).when(mockedDataSource).getConnection(); + return mockedDataSource; + } + + @Test + public void addingARoomFailsWithExceptionAsFeedbackToClient() { + assertThrows(Exception.class, () -> { + dao.add(new Room(2, "Double", 80, false)); + }); + } + + @Test + public void deletingARoomFailsWithExceptionAsFeedbackToTheClient() { + assertThrows(Exception.class, () -> { + dao.delete(existingRoom); + }); + } + + @Test + public void updatingARoomFailsWithFeedbackToTheClient() { + final var newRoomType = "Double"; + final var newPrice = 80; + final var newBookingStatus = false; + assertThrows(Exception.class, () -> { + dao.update(new Room(existingRoom.getId(), newRoomType, newPrice, newBookingStatus)); + }); + } + + @Test + public void retrievingARoomByIdFailsWithExceptionAsFeedbackToClient() { + assertThrows(Exception.class, () -> { + dao.getById(existingRoom.getId()); + }); + } + + @Test + public void retrievingAllRoomsFailsWithExceptionAsFeedbackToClient() { + assertThrows(Exception.class, () -> { + dao.getAll(); + }); + } + + } + + /** + * Delete room schema for fresh setup per test. + * + * @throws SQLException if any error occurs. + */ + @AfterEach + public void deleteSchema() throws SQLException { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); + } + } + + private void assertRoomCountIs(int count) throws Exception { + try (var allRooms = dao.getAll()) { + assertEquals(count, allRooms.count()); + } + } + + + /** + * An arbitrary number which does not correspond to an active Room id. + * + * @return an int of a room id which doesn't exist + */ + private int getNonExistingRoomId() { + return 999; + } +} diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java new file mode 100644 index 000000000..6c16b2df5 --- /dev/null +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java @@ -0,0 +1,123 @@ +package com.ashishtrivedi16.transactionscript; + +import org.h2.jdbc.JdbcSQLException; +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.Mockito.*; + +/** + * Tests {@link Hotel} + */ +public class HotelTest { + + private static final String H2_DB_URL = "jdbc:h2:~/test"; + + private Hotel hotel; + private HotelDaoImpl dao; + + @BeforeEach + public void setUp() throws Exception { + final var dataSource = createDataSource(); + deleteSchema(dataSource); + createSchema(dataSource); + dao = new HotelDaoImpl(dataSource); + addRooms(dao); + hotel = new Hotel(dao); + + } + + @Test + public void bookingRoomShouldChangeBookedStatusToTrue() throws Exception { + hotel.bookRoom(1); + assertTrue(dao.getById(1).get().isBooked()); + } + + @Test() + public void bookingRoomWithInvalidIdShouldRaiseException() { + assertThrows(Exception.class, () -> { + hotel.bookRoom(999); + }); + } + + @Test() + public void bookingRoomAgainShouldRaiseException() { + assertThrows(Exception.class, () -> { + hotel.bookRoom(1); + hotel.bookRoom(1); + }); + } + + @Test + public void NotBookingRoomShouldNotChangeBookedStatus() throws Exception { + assertFalse(dao.getById(1).get().isBooked()); + } + + @Test + public void cancelRoomBookingShouldChangeBookedStatus() throws Exception { + hotel.bookRoom(1); + assertTrue(dao.getById(1).get().isBooked()); + hotel.cancelRoomBooking(1); + assertFalse(dao.getById(1).get().isBooked()); + } + + @Test + public void cancelRoomBookingWithInvalidIdShouldRaiseException() { + assertThrows(Exception.class, () -> { + hotel.cancelRoomBooking(999); + }); + } + + @Test + public void cancelRoomBookingForUnbookedRoomShouldRaiseException() { + assertThrows(Exception.class, () -> { + hotel.cancelRoomBooking(1); + }); + } + + + private static void deleteSchema(DataSource dataSource) throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); + } + } + + private static void createSchema(DataSource dataSource) throws Exception { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); + } catch (JdbcSQLException e) { + throw new CustomException(e.getMessage(), e); + } + } + + public static DataSource createDataSource() { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setUrl(H2_DB_URL); + return dataSource; + } + + private static void addRooms(HotelDaoImpl hotelDao) throws Exception { + for (var room : generateSampleRooms()) { + hotelDao.add(room); + } + } + + public static List generateSampleRooms() { + final var room1 = new Room(1, "Single", 50, false); + final var room2 = new Room(2, "Double", 80, false); + final var room3 = new Room(3, "Queen", 120, false); + final var room4 = new Room(4, "King", 150, false); + final var room5 = new Room(5, "Single", 50, false); + final var room6 = new Room(6, "Double", 80, false); + return List.of(room1, room2, room3, room4, room5, room6); + } +} diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java new file mode 100644 index 000000000..9ea8756bd --- /dev/null +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java @@ -0,0 +1,95 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +/** + * Tests {@link Room}. + */ +public class RoomTest { + + private Room room; + private static final int ID = 1; + private static final String ROOMTYPE = "Single"; + private static final int PRICE = 50; + private static final boolean BOOKED = false; + + @BeforeEach + public void setUp() { + room = new Room(ID, ROOMTYPE, PRICE, BOOKED); + } + + @Test + public void getAndSetId() { + final var newId = 2; + room.setId(newId); + assertEquals(newId, room.getId()); + } + + @Test + public void getAndSetRoomType() { + final var newRoomType = "Double"; + room.setRoomType(newRoomType); + assertEquals(newRoomType, room.getRoomType()); + } + + @Test + public void getAndSetLastName() { + final var newPrice = 60; + room.setPrice(newPrice); + assertEquals(newPrice, room.getPrice()); + } + + @Test + public void notEqualWithDifferentId() { + final var newId = 2; + final var otherRoom = new Room(newId, ROOMTYPE, PRICE, BOOKED); + assertNotEquals(room, otherRoom); + assertNotEquals(room.hashCode(), otherRoom.hashCode()); + } + + @Test + public void equalsWithSameObjectValues() { + final var otherRoom = new Room(ID, ROOMTYPE, PRICE, BOOKED); + assertEquals(room, otherRoom); + assertEquals(room.hashCode(), otherRoom.hashCode()); + } + + @Test + public void equalsWithSameObjects() { + assertEquals(room, room); + assertEquals(room.hashCode(), room.hashCode()); + } + + @Test + public void testToString() { + assertEquals(String.format("Room{id=%s, roomType=%s, price=%s, booked=%s}", + room.getId(), room.getRoomType(), room.getPrice(), room.isBooked()), room.toString()); + } +} From 9d191324ffb3ba11e7e66eb525672528467453a0 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 26 Jul 2020 18:17:00 +0530 Subject: [PATCH 022/285] #1321 --- transaction-script/pom.xml | 35 +++++++++++++------ .../transactionscript/Hotel.java | 23 ++++++++++++ .../transactionscript/HotelDao.java | 23 ++++++++++++ .../transactionscript/HotelDaoImpl.java | 23 ++++++++++++ .../transactionscript/Room.java | 23 ++++++++++++ .../TransactionScriptApp.java | 26 ++++++++++++-- .../transactionscript/HotelTest.java | 28 ++++++++++++--- 7 files changed, 164 insertions(+), 17 deletions(-) diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index 64e824ead..f51bf36cf 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -1,4 +1,28 @@ + @@ -16,12 +40,6 @@ com.h2database h2 - - com.h2database - h2 - 1.4.200 - test - org.junit.jupiter junit-jupiter-engine @@ -31,12 +49,7 @@ org.mockito mockito-core - - com.h2database - h2 - - diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index 212a0df68..58705e5e6 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -1,3 +1,26 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; import java.util.Optional; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java index 7efa3c9e6..71d9860ba 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java @@ -1,3 +1,26 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; import java.util.Optional; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java index 88e7984a6..f1b509416 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java @@ -1,3 +1,26 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; import java.sql.Connection; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java index 55a93ddec..c4ad7bfd6 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java @@ -1,3 +1,26 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; /** diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index dfd980b46..22f4bcdd6 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -1,9 +1,31 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; -import org.h2.jdbc.JdbcSQLException; import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,7 +87,7 @@ public class TransactionScriptApp { try (var connection = dataSource.getConnection(); var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); - } catch (JdbcSQLException e) { + } catch (Exception e) { throw new CustomException(e.getMessage(), e); } } diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java index 6c16b2df5..ca1d7718c 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java @@ -1,6 +1,28 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; -import org.h2.jdbc.JdbcSQLException; import org.h2.jdbcx.JdbcDataSource; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -10,8 +32,6 @@ import java.sql.SQLException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -import static org.mockito.Mockito.*; /** * Tests {@link Hotel} @@ -94,7 +114,7 @@ public class HotelTest { try (var connection = dataSource.getConnection(); var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); - } catch (JdbcSQLException e) { + } catch (Exception e) { throw new CustomException(e.getMessage(), e); } } From 4017c37b6fcf98fd672dbcf0bcbc38bfe9f9ba12 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 26 Jul 2020 18:34:42 +0530 Subject: [PATCH 023/285] #1321 Fixed a test --- .../com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java index 01c588075..129b64c7e 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java @@ -57,6 +57,7 @@ public class HotelDaoImplTest { public void createSchema() throws SQLException { try (var connection = DriverManager.getConnection(DB_URL); var statement = connection.createStatement()) { + statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); } } From 12d392931e91c5a662e1e96d05f6f479c854ba03 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 27 Jul 2020 00:39:53 +0530 Subject: [PATCH 024/285] #1321 Added UML diagram --- transaction-script/Readme.md | 28 ++++---- .../etc/transaction-script.urm.puml | 65 +++++++++++++++++++ .../TransactionScriptApp.java | 5 +- .../transactionscript/HotelDaoImplTest.java | 1 - .../transactionscript/HotelTest.java | 13 +++- 5 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 transaction-script/etc/transaction-script.urm.puml diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index f378e5672..0d0383c44 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -1,19 +1,15 @@ ---- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ -layout: pattern # layout must always be pattern -title: Best Pattern Ever # the properly formatted title -folder: best-pattern-ever # the folder name in which this pattern lies -permalink: /patterns/best-pattern-ever/ # the permalink to the pattern, to keep this uniform please stick to /patterns/FOLDER/ -description: # short meta description that shows in Google search results - -# both categories and tags are Yaml Lists -# you can either just pick one or write a list with '-'s -# usable categories and tags are listed here: https://github.com/iluwatar/java-design-patterns/blob/gh-pages/_config.yml -categories: creational # categories of the pattern -tags: # tags of the pattern - - best - - ever - - awesome --- +layout: pattern +title: Transaction script +folder: transaction-script +permalink: /patterns/transaction-script/ +categories: Domain logic +tags: + - Data access +--- + +## Intent +Transaction script(TS) is mainly used in small applications where nothing complex is done and bigger architecture's are not needed. ## Name / classification ... @@ -21,8 +17,6 @@ tags: # tags of the pattern ## Also known as ... -## Intent -... ## Explanation ... diff --git a/transaction-script/etc/transaction-script.urm.puml b/transaction-script/etc/transaction-script.urm.puml new file mode 100644 index 000000000..4a5bf02f8 --- /dev/null +++ b/transaction-script/etc/transaction-script.urm.puml @@ -0,0 +1,65 @@ +@startuml +package com.ashishtrivedi16.transaction-script { + class TransactionScriptApp { + - H2_DB_URL : String {static} + - LOGGER : Logger {static} + - addRooms(hotelDaoImpl : HotelDaoImpl) {static} + - createDataSource() : DataSource {static} + - createSchema(dataSource : DataSource) {static} + - deleteSchema(dataSource : DataSource) {static} + - getRoomsStatus(hotelDaoImpl : HotelDaoImpl) {static} + - generateSampleRooms() : List {static} + + main(args : String[]) {static} + } + class Room { + - id: Int + - roomType: String + - price: Int + - booked: Boolean + + Customer(id : int, roomType : String, price: Int, booked: Boolean) + + getId() : int + + getRoomType() : String + + getPrice() : Int + + isBooked() : Boolean + + setId(id : int) + + setRoomType(roomType : String) + + setPrice(price : Int) + + setBooked(booked : boolean) + + equals(that : Object) : boolean + + hashCode() : int + + toString() : String + } + interface HotelDao { + + add(Room) : boolean {abstract} + + delete(Room) : boolean {abstract} + + getAll() : Stream {abstract} + + getById(int) : Optional {abstract} + + update(Room) : boolean {abstract} + } + class RoomSchemaSql { + + CREATE_SCHEMA_SQL : String {static} + + DELETE_SCHEMA_SQL : String {static} + - RoomSchemaSql() + } + class HotelDaoImpl { + - dataSource : DataSource + + HotelDaoImpl(dataSource : DataSource) + + add(room : Room) : boolean + - createRoom(resultSet : ResultSet) : Room + + delete(room : Room) : boolean + + getAll() : Stream + + getById(id : int) : Optional + - getConnection() : Connection + - mutedClose(connection : Connection, statement : PreparedStatement, resultSet : ResultSet) + + update(room : Room) : boolean + } + class Hotel { + - LOGGER : Logger {static} + - hotelDao: HotelDaoImpl + + Hotel(hotelDao: HotelDaoImpl) + + bookRoom(roomNumber: Int) + + cancelRoomBooking(roomNumber: Int) + } +} +HotelDaoImpl ..|> HotelDao +@enduml diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index 22f4bcdd6..13a19dd48 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -47,6 +47,7 @@ public class TransactionScriptApp { deleteSchema(dataSource); createSchema(dataSource); final var dao = new HotelDaoImpl(dataSource); + addRooms(dao); getRoomStatus(dao); @@ -97,7 +98,7 @@ public class TransactionScriptApp { * * @return h2 datasource */ - public static DataSource createDataSource() { + private static DataSource createDataSource() { JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setUrl(H2_DB_URL); return dataSource; @@ -114,7 +115,7 @@ public class TransactionScriptApp { * * @return list of rooms */ - public static List generateSampleRooms() { + private static List generateSampleRooms() { final var room1 = new Room(1, "Single", 50, false); final var room2 = new Room(2, "Double", 80, false); final var room3 = new Room(3, "Queen", 120, false); diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java index 129b64c7e..6e907fdc0 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java @@ -261,7 +261,6 @@ public class HotelDaoImplTest { } } - /** * An arbitrary number which does not correspond to an active Room id. * diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java index ca1d7718c..62aad9527 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java @@ -63,7 +63,7 @@ public class HotelTest { @Test() public void bookingRoomWithInvalidIdShouldRaiseException() { assertThrows(Exception.class, () -> { - hotel.bookRoom(999); + hotel.bookRoom(getNonExistingRoomId()); }); } @@ -91,7 +91,7 @@ public class HotelTest { @Test public void cancelRoomBookingWithInvalidIdShouldRaiseException() { assertThrows(Exception.class, () -> { - hotel.cancelRoomBooking(999); + hotel.cancelRoomBooking(getNonExistingRoomId()); }); } @@ -140,4 +140,13 @@ public class HotelTest { final var room6 = new Room(6, "Double", 80, false); return List.of(room1, room2, room3, room4, room5, room6); } + + /** + * An arbitrary number which does not correspond to an active Room id. + * + * @return an int of a room id which doesn't exist + */ + private int getNonExistingRoomId() { + return 999; + } } From 2fdd7a11e93c38d0a3496f09232fa10c51de3f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:40:42 +0300 Subject: [PATCH 025/285] SonarQube check runs only in master branch (workaround for https://jira.sonarsource.com/browse/MMF-1371) --- .github/workflows/maven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 53460c97d..01caaab67 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -46,7 +46,13 @@ jobs: # Some tests need screen access - name: Install xvfb run: sudo apt-get install xvfb + # SonarQube scan does not work for forked repositories + # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven + if: github.ref != ‘refs/heads/master’ + run: xvfb-run mvn clean verify + - name: Build with Maven and run SonarQube analysis + if: github.ref == ‘refs/heads/master’ run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From eee409f2840d6276826f8577fd5408afa52e7a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:44:54 +0300 Subject: [PATCH 026/285] Fix syntax --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 01caaab67..336c103d6 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,10 +49,10 @@ jobs: # SonarQube scan does not work for forked repositories # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven - if: github.ref != ‘refs/heads/master’ + if: "github.ref != ‘refs/heads/master’" run: xvfb-run mvn clean verify - name: Build with Maven and run SonarQube analysis - if: github.ref == ‘refs/heads/master’ + if: "github.ref == ‘refs/heads/master’" run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From 4b88214baef78c362806311d88f96bebb0cd4d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 26 Jul 2020 22:47:33 +0300 Subject: [PATCH 027/285] Fix syntax --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 336c103d6..d18cad280 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -49,10 +49,10 @@ jobs: # SonarQube scan does not work for forked repositories # See https://jira.sonarsource.com/browse/MMF-1371 - name: Build with Maven - if: "github.ref != ‘refs/heads/master’" + if: github.ref != 'refs/heads/master' run: xvfb-run mvn clean verify - name: Build with Maven and run SonarQube analysis - if: "github.ref == ‘refs/heads/master’" + if: github.ref == 'refs/heads/master' run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis From 54c0b1725c522666e7dbdcb973719cefb7a9daed Mon Sep 17 00:00:00 2001 From: amit1307 Date: Mon, 27 Jul 2020 14:50:32 +0100 Subject: [PATCH 028/285] Fix broken logging in service layer (#1342) --- service-layer/src/main/resources/logback.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/service-layer/src/main/resources/logback.xml b/service-layer/src/main/resources/logback.xml index 47fe42236..e6678aff2 100644 --- a/service-layer/src/main/resources/logback.xml +++ b/service-layer/src/main/resources/logback.xml @@ -43,6 +43,7 @@ + From b62bed7e433591af1585aa13ca8b7aecd1842e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 18:28:12 +0300 Subject: [PATCH 029/285] #590 explanation for Promise --- promise/README.md | 278 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 6 deletions(-) diff --git a/promise/README.md b/promise/README.md index cf3d96c88..993d29a9f 100644 --- a/promise/README.md +++ b/promise/README.md @@ -9,18 +9,277 @@ tags: --- ## Also known as + CompletableFuture ## Intent -A Promise represents a proxy for a value not necessarily known when the promise is created. It -allows you to associate dependent promises to an asynchronous action's eventual success value or -failure reason. Promises are a way to write async code that still appears as though it is executing -in a synchronous way. + +A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate +dependent promises to an asynchronous action's eventual success value or failure reason. Promises are a way to write +async code that still appears as though it is executing in a synchronous way. + +## Explanation + +The Promise object is used for asynchronous computations. A Promise represents an operation that hasn't completed yet, +but is expected in the future. + +Promises provide a few advantages over callback objects: + * Functional composition and error handling + * Prevents callback hell and provides callback aggregation + +Real world example + +> We are developing a software solution that downloads files and calculates the number of lines and character +frequencies in those files. Promise is an ideal solution to make the code concise and easy to understand. + +In plain words + +> Promise is a placeholder for an asynchronous operation that is ongoing. + +Wikipedia says + +> In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program +execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is +initially unknown, usually because the computation of its value is not yet complete. + +**Programmatic Example** + +In the example a file is downloaded and its line count is calculated. The calculated line count is then consumed and +printed on console. + +Let's first introduce a support class we need for implementation. Here's `PromiseSupport`. + +```java +class PromiseSupport implements Future { + + private static final Logger LOGGER = LoggerFactory.getLogger(PromiseSupport.class); + + private static final int RUNNING = 1; + private static final int FAILED = 2; + private static final int COMPLETED = 3; + + private final Object lock; + + private volatile int state = RUNNING; + private T value; + private Exception exception; + + PromiseSupport() { + this.lock = new Object(); + } + + void fulfill(T value) { + this.value = value; + this.state = COMPLETED; + synchronized (lock) { + lock.notifyAll(); + } + } + + void fulfillExceptionally(Exception exception) { + this.exception = exception; + this.state = FAILED; + synchronized (lock) { + lock.notifyAll(); + } + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return state > RUNNING; + } + + @Override + public T get() throws InterruptedException, ExecutionException { + synchronized (lock) { + while (state == RUNNING) { + lock.wait(); + } + } + if (state == COMPLETED) { + return value; + } + throw new ExecutionException(exception); + } + + @Override + public T get(long timeout, TimeUnit unit) throws ExecutionException { + synchronized (lock) { + while (state == RUNNING) { + try { + lock.wait(unit.toMillis(timeout)); + } catch (InterruptedException e) { + LOGGER.warn("Interrupted!", e); + Thread.currentThread().interrupt(); + } + } + } + + if (state == COMPLETED) { + return value; + } + throw new ExecutionException(exception); + } +} +``` + +With `PromiseSupport` in place we can implement the actual `Promise`. + +```java +public class Promise extends PromiseSupport { + + private Runnable fulfillmentAction; + private Consumer exceptionHandler; + + public Promise() { + } + + @Override + public void fulfill(T value) { + super.fulfill(value); + postFulfillment(); + } + + @Override + public void fulfillExceptionally(Exception exception) { + super.fulfillExceptionally(exception); + handleException(exception); + postFulfillment(); + } + + private void handleException(Exception exception) { + if (exceptionHandler == null) { + return; + } + exceptionHandler.accept(exception); + } + + private void postFulfillment() { + if (fulfillmentAction == null) { + return; + } + fulfillmentAction.run(); + } + + public Promise fulfillInAsync(final Callable task, Executor executor) { + executor.execute(() -> { + try { + fulfill(task.call()); + } catch (Exception ex) { + fulfillExceptionally(ex); + } + }); + return this; + } + + public Promise thenAccept(Consumer action) { + var dest = new Promise(); + fulfillmentAction = new ConsumeAction(this, dest, action); + return dest; + } + + public Promise onError(Consumer exceptionHandler) { + this.exceptionHandler = exceptionHandler; + return this; + } + + public Promise thenApply(Function func) { + Promise dest = new Promise<>(); + fulfillmentAction = new TransformAction(this, dest, func); + return dest; + } + + private class ConsumeAction implements Runnable { + + private final Promise src; + private final Promise dest; + private final Consumer action; + + private ConsumeAction(Promise src, Promise dest, Consumer action) { + this.src = src; + this.dest = dest; + this.action = action; + } + + @Override + public void run() { + try { + action.accept(src.get()); + dest.fulfill(null); + } catch (Throwable throwable) { + dest.fulfillExceptionally((Exception) throwable.getCause()); + } + } + } + + private class TransformAction implements Runnable { + + private final Promise src; + private final Promise dest; + private final Function func; + + private TransformAction(Promise src, Promise dest, Function func) { + this.src = src; + this.dest = dest; + this.func = func; + } + + @Override + public void run() { + try { + dest.fulfill(func.apply(src.get())); + } catch (Throwable throwable) { + dest.fulfillExceptionally((Exception) throwable.getCause()); + } + } + } +} +``` + +Now we can show the full example in action. Here's how to download and count the number of lines in a file using +`Promise`. + +```java + countLines().thenAccept( + count -> { + LOGGER.info("Line count is: {}", count); + taskCompleted(); + } + ); + + private Promise countLines() { + return download(DEFAULT_URL).thenApply(Utility::countLines); + } + + private Promise download(String urlString) { + return new Promise() + .fulfillInAsync( + () -> Utility.downloadFile(urlString), executor) + .onError( + throwable -> { + throwable.printStackTrace(); + taskCompleted(); + } + ); + } +``` ## Class diagram + ![alt text](./etc/promise.png "Promise") ## Applicability + Promise pattern is applicable in concurrent programming when some work needs to be done asynchronously and: @@ -35,10 +294,17 @@ and: * [Guava ListenableFuture](https://github.com/google/guava/wiki/ListenableFutureExplained) ## Related Patterns - * Async Method Invocation - * Callback + + * [Async Method Invocation](https://java-design-patterns.com/patterns/async-method-invocation/) + * [Callback](https://java-design-patterns.com/patterns/callback/) + +## Tutorials + +* [Guide To CompletableFuture](https://www.baeldung.com/java-completablefuture) ## Credits * [You are missing the point to Promises](https://gist.github.com/domenic/3889970) * [Functional style callbacks using CompletableFuture](https://www.infoq.com/articles/Functional-Style-Callbacks-Using-CompletableFuture) +* [Java 8 in Action: Lambdas, Streams, and functional-style programming](https://www.amazon.com/gp/product/1617291994/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617291994&linkId=995af46887bb7b65e6c788a23eaf7146) +* [Modern Java in Action: Lambdas, streams, functional and reactive programming](https://www.amazon.com/gp/product/1617293563/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617293563&linkId=f70fe0d3e1efaff89554a6479c53759c) From ef4de30310fa46c95c562612c3863ddd1200db92 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 20:59:08 +0300 Subject: [PATCH 030/285] docs: add iluwatar as a contributor (#1343) * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 24 ++++++++++++++++++++++++ README.md | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 .all-contributorsrc diff --git a/.all-contributorsrc b/.all-contributorsrc new file mode 100644 index 000000000..4e92d6568 --- /dev/null +++ b/.all-contributorsrc @@ -0,0 +1,24 @@ +{ + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + "contributors": [ + { + "login": "iluwatar", + "name": "Ilkka Seppälä", + "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", + "profile": "https://github.com/iluwatar", + "contributions": [ + "code" + ] + } + ], + "contributorsPerLine": 7, + "projectName": "java-design-patterns", + "projectOwner": "iluwatar", + "repoType": "github", + "repoHost": "https://github.com", + "skipCi": true +} diff --git a/README.md b/README.md index 2eabb5e82..533eec47e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ +[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) + that smart and dearly wants an empty line before a heading to be able to display it as such, e.g. website) --> @@ -58,3 +61,22 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata # License This project is licensed under the terms of the MIT license. + +## Contributors ✨ + +Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + +

Ilkka Seppälä

💻
+ + + + + +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! \ No newline at end of file From 93c11fdf233e19f75b8a39afa7e7dbd8c2d87157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 21:01:48 +0300 Subject: [PATCH 031/285] Update README.md --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 533eec47e..d7148dde7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) - that smart and dearly wants an empty line before a heading to be able to display it as such, e.g. website) --> @@ -11,6 +8,9 @@ [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) + +[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) + # Introduction @@ -62,9 +62,7 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata This project is licensed under the terms of the MIT license. -## Contributors ✨ - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): +# Contributors @@ -79,4 +77,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! \ No newline at end of file +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From b7d122f6146c3ae36750a9eaef0083649749800d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:13:13 +0300 Subject: [PATCH 032/285] docs: add iluwatar as a contributor (#1344) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 3 ++- README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4e92d6568..80d7f54b4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -11,7 +11,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", "profile": "https://github.com/iluwatar", "contributions": [ - "code" + "code", + "projectManagement" ] } ], diff --git a/README.md b/README.md index d7148dde7..55f11e702 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ This project is licensed under the terms of the MIT license. - +

Ilkka Seppälä

💻

Ilkka Seppälä

💻 📆
From ae7a0b8a4a331ccf96d6dbd956c4fd1c541888ed Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:17:52 +0300 Subject: [PATCH 033/285] docs: add amit1307 as a contributor (#1345) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 80d7f54b4..d919371f1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -14,6 +14,15 @@ "code", "projectManagement" ] + }, + { + "login": "amit1307", + "name": "amit1307", + "avatar_url": "https://avatars0.githubusercontent.com/u/23420222?v=4", + "profile": "https://github.com/amit1307", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 55f11e702..04ddf6372 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -70,6 +70,7 @@ This project is licensed under the terms of the MIT license. +

Ilkka Seppälä

💻 📆

amit1307

💻
From 76f634ff7a10f4a9f1840680938318bd02af2738 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 21:50:31 +0300 Subject: [PATCH 034/285] docs: add iluwatar as a contributor (#1346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 8 ++++++++ README.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d919371f1..dbf65aeb8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -12,6 +12,14 @@ "profile": "https://github.com/iluwatar", "contributions": [ "code", + "projectManagement", + "maintenance", + "blog", + "content", + "doc", + "ideas", + "infra", + "review" "projectManagement" ] }, diff --git a/README.md b/README.md index 04ddf6372..279f02028 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ This project is licensed under the terms of the MIT license. - +

Ilkka Seppälä

💻 📆

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀

amit1307

💻
From 02b6aba6ae25aae1c23823c0b458782d859f1e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 22:38:07 +0300 Subject: [PATCH 035/285] fix config syntax --- .all-contributorsrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index dbf65aeb8..9c7f063a7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -19,7 +19,7 @@ "doc", "ideas", "infra", - "review" + "review", "projectManagement" ] }, From 211d7903ae480e05cef03795779a00115050b216 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 22:40:20 +0300 Subject: [PATCH 036/285] docs: add npathai as a contributor (#1347) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 13 +++++++++++++ README.md | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9c7f063a7..90490c998 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -31,6 +31,19 @@ "contributions": [ "code" ] + }, + { + "login": "npathai", + "name": "Narendra Pathai", + "avatar_url": "https://avatars2.githubusercontent.com/u/1792515?v=4", + "profile": "https://github.com/npathai", + "contributions": [ + "code", + "ideas", + "maintenance", + "question", + "review" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 279f02028..bce11a908 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -69,8 +69,9 @@ This project is licensed under the terms of the MIT license. - + +

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆

amit1307

💻

Narendra Pathai

💻 🤔 🚧 💬 👀
From aea90ab115039ac008194e2743b365f2e2da3df4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 22:48:15 +0300 Subject: [PATCH 037/285] docs: add fluxw42 as a contributor (#1348) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 90490c998..25335e77a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -44,6 +44,15 @@ "question", "review" ] + }, + { + "login": "fluxw42", + "name": "Jeroen Meulemeester", + "avatar_url": "https://avatars1.githubusercontent.com/u/1545460?v=4", + "profile": "https://github.com/fluxw42", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index bce11a908..7525ddb43 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -72,6 +72,7 @@ This project is licensed under the terms of the MIT license.
Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆
amit1307

💻
Narendra Pathai

💻 🤔 🚧 💬 👀 +
Jeroen Meulemeester

💻 From 2c8535e839223a445220bef981b5591da12e4c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 27 Jul 2020 23:07:58 +0300 Subject: [PATCH 038/285] max 3 contribution types per person --- .all-contributorsrc | 11 +---------- README.md | 4 ++-- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 25335e77a..8e44fd9e2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -11,16 +11,9 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4", "profile": "https://github.com/iluwatar", "contributions": [ - "code", "projectManagement", "maintenance", - "blog", - "content", - "doc", - "ideas", - "infra", - "review", - "projectManagement" + "content" ] }, { @@ -40,8 +33,6 @@ "contributions": [ "code", "ideas", - "maintenance", - "question", "review" ] }, diff --git a/README.md b/README.md index 7525ddb43..ba9fd307e 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,9 @@ This project is licensed under the terms of the MIT license. - + - +

Ilkka Seppälä

💻 📆 🚧 📝 🖋 📖 🤔 🚇 👀 📆

Ilkka Seppälä

📆 🚧 🖋

amit1307

💻

Narendra Pathai

💻 🤔 🚧 💬 👀

Narendra Pathai

💻 🤔 👀

Jeroen Meulemeester

💻
From 05dfd31fb7e55e185499f7fa3a2944b2690853c9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:14:34 +0300 Subject: [PATCH 039/285] docs: add mikulucky as a contributor (#1349) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8e44fd9e2..cecc9e2dc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -44,6 +44,15 @@ "contributions": [ "code" ] + }, + { + "login": "mikulucky", + "name": "Joseph McCarthy", + "avatar_url": "https://avatars0.githubusercontent.com/u/4526195?v=4", + "profile": "http://www.joemccarthy.co.uk", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ba9fd307e..743017959 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -69,10 +69,11 @@ This project is licensed under the terms of the MIT license. - + +

Ilkka Seppälä

📆 🚧 🖋

Ilkka Seppälä

📆 🚧 🖋

amit1307

💻

Narendra Pathai

💻 🤔 👀

Jeroen Meulemeester

💻

Joseph McCarthy

💻
From 64eff5eb93da95bf55ce48222d1f41200424e785 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:18:02 +0300 Subject: [PATCH 040/285] docs: add thomasoss as a contributor (#1350) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index cecc9e2dc..68751f4a7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -53,6 +53,15 @@ "contributions": [ "code" ] + }, + { + "login": "thomasoss", + "name": "Thomas", + "avatar_url": "https://avatars1.githubusercontent.com/u/22516154?v=4", + "profile": "https://github.com/thomasoss", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 743017959..08f10e096 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -74,6 +74,7 @@ This project is licensed under the terms of the MIT license.
Narendra Pathai

💻 🤔 👀
Jeroen Meulemeester

💻
Joseph McCarthy

💻 +
Thomas

💻 From 09dd0bee30519c7b4e0539744b2cb7a2f222fe97 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:20:44 +0300 Subject: [PATCH 041/285] docs: add anuragagarwal561994 as a contributor (#1351) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 68751f4a7..a3ed0c8f2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -62,6 +62,15 @@ "contributions": [ "code" ] + }, + { + "login": "anuragagarwal561994", + "name": "Anurag Agarwal", + "avatar_url": "https://avatars1.githubusercontent.com/u/6075379?v=4", + "profile": "https://github.com/anuragagarwal561994", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 08f10e096..d8231ef7e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -75,6 +75,7 @@ This project is licensed under the terms of the MIT license.
Jeroen Meulemeester

💻
Joseph McCarthy

💻
Thomas

💻 +
Anurag Agarwal

💻 From d609f3eec69488e021b3bd34c9c08114b11f9c95 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:26:03 +0300 Subject: [PATCH 042/285] docs: add markusmo3 as a contributor (#1352) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 11 +++++++++++ README.md | 5 ++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a3ed0c8f2..4fda28295 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -71,6 +71,17 @@ "contributions": [ "code" ] + }, + { + "login": "markusmo3", + "name": "Markus Moser", + "avatar_url": "https://avatars1.githubusercontent.com/u/3317416?v=4", + "profile": "https://markusmo3.github.io", + "contributions": [ + "design", + "code", + "ideas" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d8231ef7e..d8f9f5e7a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -77,6 +77,9 @@ This project is licensed under the terms of the MIT license.
Thomas

💻
Anurag Agarwal

💻 + +
Markus Moser

🎨 💻 🤔 + From b3eb6ccea424c54bf7cfab8c2ac36b8c467dd53e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:28:35 +0300 Subject: [PATCH 043/285] docs: add isabiq as a contributor (#1353) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4fda28295..113d84373 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -82,6 +82,15 @@ "code", "ideas" ] + }, + { + "login": "isabiq", + "name": "Sabiq Ihab", + "avatar_url": "https://avatars1.githubusercontent.com/u/19510920?v=4", + "profile": "https://twitter.com/i_sabiq", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d8f9f5e7a..c3aa4249e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -79,6 +79,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔 +
Sabiq Ihab

💻 From 960adfc37a3fd30bdf33f2c75256c79e8ce1d7ca Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:30:42 +0300 Subject: [PATCH 044/285] docs: add inbravo as a contributor (#1354) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 113d84373..8bcf19fb5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -91,6 +91,15 @@ "contributions": [ "code" ] + }, + { + "login": "inbravo", + "name": "Amit Dixit", + "avatar_url": "https://avatars3.githubusercontent.com/u/5253764?v=4", + "profile": "http://inbravo.github.io", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index c3aa4249e..4dee660b8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -80,6 +80,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻 +
Amit Dixit

💻 From 781a7c8b52af7ff3edde4bb89ceb4456ed3b897c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:32:58 +0300 Subject: [PATCH 045/285] docs: add piyushchaudhari04 as a contributor (#1355) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8bcf19fb5..1b3b280e2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -100,6 +100,15 @@ "contributions": [ "code" ] + }, + { + "login": "piyushchaudhari04", + "name": "Piyush Kailash Chaudhari", + "avatar_url": "https://avatars3.githubusercontent.com/u/10268029?v=4", + "profile": "https://github.com/piyushchaudhari04", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 4dee660b8..4f5c8b5b7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-10-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -81,6 +81,7 @@ This project is licensed under the terms of the MIT license.
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻
Amit Dixit

💻 +
Piyush Kailash Chaudhari

💻 From d6edeee326d03e8d85a246889afb6ef41e3f5d50 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:35:49 +0300 Subject: [PATCH 046/285] docs: add joshzambales as a contributor (#1356) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1b3b280e2..bd011b233 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -109,6 +109,15 @@ "contributions": [ "code" ] + }, + { + "login": "joshzambales", + "name": "joshzambales", + "avatar_url": "https://avatars1.githubusercontent.com/u/8704552?v=4", + "profile": "https://github.com/joshzambales", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 4f5c8b5b7..5c559363f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-11-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -82,6 +82,7 @@ This project is licensed under the terms of the MIT license.
Sabiq Ihab

💻
Amit Dixit

💻
Piyush Kailash Chaudhari

💻 +
joshzambales

💻 From 1cb9c2bcde9c8a1c32e453bf4ab273b25b878e97 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:37:56 +0300 Subject: [PATCH 047/285] docs: add Crossy147 as a contributor (#1357) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bd011b233..fdd99c31c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -118,6 +118,15 @@ "contributions": [ "code" ] + }, + { + "login": "Crossy147", + "name": "Kamil Pietruszka", + "avatar_url": "https://avatars2.githubusercontent.com/u/7272996?v=4", + "profile": "https://github.com/Crossy147", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 5c559363f..d21e9a476 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-12-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -83,6 +83,7 @@ This project is licensed under the terms of the MIT license.
Amit Dixit

💻
Piyush Kailash Chaudhari

💻
joshzambales

💻 +
Kamil Pietruszka

💻 From 8ba111fe60ffe21d6155cc98c82a7907814ba752 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:40:28 +0300 Subject: [PATCH 048/285] docs: add zafarella as a contributor (#1358) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 10 ++++++++++ README.md | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index fdd99c31c..eb77506ca 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -127,6 +127,16 @@ "contributions": [ "code" ] + }, + { + "login": "zafarella", + "name": "Zafar Khaydarov", + "avatar_url": "https://avatars2.githubusercontent.com/u/660742?v=4", + "profile": "http://cs.joensuu.fi/~zkhayda", + "contributions": [ + "code", + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d21e9a476..cee9e18bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -84,6 +84,7 @@ This project is licensed under the terms of the MIT license.
Piyush Kailash Chaudhari

💻
joshzambales

💻
Kamil Pietruszka

💻 +
Zafar Khaydarov

💻 📖 From 80605283f55a0abe33b01f4d337304d0107b64e2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:42:27 +0300 Subject: [PATCH 049/285] docs: add kemitix as a contributor (#1359) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index eb77506ca..387c34849 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -137,6 +137,15 @@ "code", "doc" ] + }, + { + "login": "kemitix", + "name": "Paul Campbell", + "avatar_url": "https://avatars1.githubusercontent.com/u/1147749?v=4", + "profile": "https://kemitix.github.io/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index cee9e18bc..95d2724e6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-14-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -86,6 +86,9 @@ This project is licensed under the terms of the MIT license.
Kamil Pietruszka

💻
Zafar Khaydarov

💻 📖 + +
Paul Campbell

💻 + From cf8e366e2518af8354f1879d3caf690ff0b93194 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:44:46 +0300 Subject: [PATCH 050/285] docs: add Argyro-Sioziou as a contributor (#1360) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 387c34849..a07d447af 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -146,6 +146,15 @@ "contributions": [ "code" ] + }, + { + "login": "Argyro-Sioziou", + "name": "Argyro Sioziou", + "avatar_url": "https://avatars0.githubusercontent.com/u/22822639?v=4", + "profile": "https://github.com/Argyro-Sioziou", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 95d2724e6..d1ca6e8bc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -88,6 +88,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻 +
Argyro Sioziou

💻 From a77e9620b5274321e1753de42c3945d14b2bc2fd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:46:41 +0300 Subject: [PATCH 051/285] docs: add TylerMcConville as a contributor (#1361) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a07d447af..eb1b24798 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -155,6 +155,15 @@ "contributions": [ "code" ] + }, + { + "login": "TylerMcConville", + "name": "TylerMcConville", + "avatar_url": "https://avatars0.githubusercontent.com/u/4946449?v=4", + "profile": "https://github.com/TylerMcConville", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d1ca6e8bc..b73859360 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -89,6 +89,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻
Argyro Sioziou

💻 +
TylerMcConville

💻 From f360b64877fb459666c597fc0985408c49481af7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:48:50 +0300 Subject: [PATCH 052/285] docs: add saksham93 as a contributor (#1362) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index eb1b24798..81e67d559 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -164,6 +164,15 @@ "contributions": [ "code" ] + }, + { + "login": "saksham93", + "name": "saksham93", + "avatar_url": "https://avatars1.githubusercontent.com/u/37399540?v=4", + "profile": "https://github.com/saksham93", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b73859360..833d65eae 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-17-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -90,6 +90,7 @@ This project is licensed under the terms of the MIT license.
Paul Campbell

💻
Argyro Sioziou

💻
TylerMcConville

💻 +
saksham93

💻 From c85d764e397029aedd3148a8338fabebf2956f88 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:50:39 +0300 Subject: [PATCH 053/285] docs: add nikhilbarar as a contributor (#1363) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 81e67d559..61f88d89a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -173,6 +173,15 @@ "contributions": [ "code" ] + }, + { + "login": "nikhilbarar", + "name": "nikhilbarar", + "avatar_url": "https://avatars2.githubusercontent.com/u/37332144?v=4", + "profile": "https://github.com/nikhilbarar", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 833d65eae..ccfa6e4ff 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -91,6 +91,7 @@ This project is licensed under the terms of the MIT license.
Argyro Sioziou

💻
TylerMcConville

💻
saksham93

💻 +
nikhilbarar

💻 From 4c766b9e71fe927e2fd39003d7f44c2a70c7b024 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:52:39 +0300 Subject: [PATCH 054/285] docs: add colinbut as a contributor (#1364) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 61f88d89a..c90df750f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -182,6 +182,15 @@ "contributions": [ "code" ] + }, + { + "login": "colinbut", + "name": "Colin But", + "avatar_url": "https://avatars2.githubusercontent.com/u/10725674?v=4", + "profile": "http://colinbut.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index ccfa6e4ff..5fa2d303e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -92,6 +92,7 @@ This project is licensed under the terms of the MIT license.
TylerMcConville

💻
saksham93

💻
nikhilbarar

💻 +
Colin But

💻 From d8f12529f2703845cd58c253ba7886c379ec9630 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:55:47 +0300 Subject: [PATCH 055/285] docs: add ruslanpa as a contributor (#1365) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c90df750f..28abe71da 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -191,6 +191,15 @@ "contributions": [ "code" ] + }, + { + "login": "ruslanpa", + "name": "Ruslan", + "avatar_url": "https://avatars2.githubusercontent.com/u/1503411?v=4", + "profile": "https://github.com/ruslanpa", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 5fa2d303e..559f2a69c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-21-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -93,6 +93,7 @@ This project is licensed under the terms of the MIT license.
saksham93

💻
nikhilbarar

💻
Colin But

💻 +
Ruslan

💻 From 97adc13a1bcf09bf45d4a1a37b1384caa1de9b7a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:57:26 +0300 Subject: [PATCH 056/285] docs: add JuhoKang as a contributor (#1366) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 28abe71da..d532a2baf 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -200,6 +200,15 @@ "contributions": [ "code" ] + }, + { + "login": "JuhoKang", + "name": "Juho Kang", + "avatar_url": "https://avatars1.githubusercontent.com/u/4745294?v=4", + "profile": "https://github.com/JuhoKang", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 559f2a69c..eab98e6c0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-21-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -95,6 +95,9 @@ This project is licensed under the terms of the MIT license.
Colin But

💻
Ruslan

💻 + +
Juho Kang

💻 + From a5ff32c13ea3d66794bda314bc542a93eafa08aa Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:02:49 +0300 Subject: [PATCH 057/285] docs: add dheeraj-mummareddy as a contributor (#1367) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d532a2baf..5f5df0ed5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -209,6 +209,15 @@ "contributions": [ "code" ] + }, + { + "login": "dheeraj-mummareddy", + "name": "Dheeraj Mummareddy", + "avatar_url": "https://avatars2.githubusercontent.com/u/7002230?v=4", + "profile": "https://github.com/dheeraj-mummareddy", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index eab98e6c0..912cc1b25 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-22-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -97,6 +97,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻 +
Dheeraj Mummareddy

💻 From 0563ac7645484ea12382d1c7240873c7607dbbc9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:08:01 +0300 Subject: [PATCH 058/285] docs: add bernardosulzbach as a contributor (#1368) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5f5df0ed5..512859f34 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -218,6 +218,15 @@ "contributions": [ "code" ] + }, + { + "login": "bernardosulzbach", + "name": "Bernardo Sulzbach", + "avatar_url": "https://avatars0.githubusercontent.com/u/8271090?v=4", + "profile": "https://www.bernardosulzbach.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 912cc1b25..bb324ec26 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -98,6 +98,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻
Dheeraj Mummareddy

💻 +
Bernardo Sulzbach

💻 From 5b269d5af1e7dd3eaf7b0e9e5b4363faedbb5abd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:09:43 +0300 Subject: [PATCH 059/285] docs: add 4lexis as a contributor (#1369) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 512859f34..3d129d1a1 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -227,6 +227,15 @@ "contributions": [ "code" ] + }, + { + "login": "4lexis", + "name": "Aleksandar Dudukovic", + "avatar_url": "https://avatars0.githubusercontent.com/u/19871727?v=4", + "profile": "https://github.com/4lexis", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index bb324ec26..8da13c04e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -99,6 +99,7 @@ This project is licensed under the terms of the MIT license.
Juho Kang

💻
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻 +
Aleksandar Dudukovic

💻 From 03ebd5f353edcb6becfc0e6c1ca1944e131c689d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:11:29 +0300 Subject: [PATCH 060/285] docs: add yusufaytas as a contributor (#1370) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3d129d1a1..2d1a8c2ab 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -236,6 +236,15 @@ "contributions": [ "code" ] + }, + { + "login": "yusufaytas", + "name": "Yusuf Aytaş", + "avatar_url": "https://avatars2.githubusercontent.com/u/1049483?v=4", + "profile": "https://www.yusufaytas.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 8da13c04e..d3485ec5c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-26-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -100,6 +100,7 @@ This project is licensed under the terms of the MIT license.
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻
Aleksandar Dudukovic

💻 +
Yusuf Aytaş

💻 From 2706c8fc37037d7a5fa7bca319038112d3addc3b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:13:03 +0300 Subject: [PATCH 061/285] docs: add qpi as a contributor (#1371) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2d1a8c2ab..d51e82608 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -245,6 +245,15 @@ "contributions": [ "code" ] + }, + { + "login": "qpi", + "name": "Mihály Kuprivecz", + "avatar_url": "https://avatars2.githubusercontent.com/u/1001491?v=4", + "profile": "http://futurehomes.hu", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index d3485ec5c..2646704d8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-26-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-27-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -101,6 +101,7 @@ This project is licensed under the terms of the MIT license.
Bernardo Sulzbach

💻
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻 +
Mihály Kuprivecz

💻 From 452981669b5b95a0b3c78453a456eaf22f4cc2e7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:14:37 +0300 Subject: [PATCH 062/285] docs: add kapinuss as a contributor (#1372) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d51e82608..42d3fd6ce 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -254,6 +254,15 @@ "contributions": [ "code" ] + }, + { + "login": "kapinuss", + "name": "Stanislav Kapinus", + "avatar_url": "https://avatars0.githubusercontent.com/u/17639945?v=4", + "profile": "https://github.com/kapinuss", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 2646704d8..b8ea48ef0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-27-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -102,6 +102,7 @@ This project is licensed under the terms of the MIT license.
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻
Mihály Kuprivecz

💻 +
Stanislav Kapinus

💻 From 0cff538c271ffdae6eb6adadc9ac4fde7f7fe2fc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:16:14 +0300 Subject: [PATCH 063/285] docs: add gvsharma as a contributor (#1373) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 42d3fd6ce..ceefb272f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -263,6 +263,15 @@ "contributions": [ "code" ] + }, + { + "login": "gvsharma", + "name": "GVSharma", + "avatar_url": "https://avatars1.githubusercontent.com/u/6648152?v=4", + "profile": "https://github.com/gvsharma", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index b8ea48ef0..3ec2bcbab 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-29-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -104,6 +104,9 @@ This project is licensed under the terms of the MIT license.
Mihály Kuprivecz

💻
Stanislav Kapinus

💻 + +
GVSharma

💻 + From b805a7526eb7b741933a041992f0b610b50d0390 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:17:42 +0300 Subject: [PATCH 064/285] docs: add SrdjanPaunovic as a contributor (#1374) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ceefb272f..7c71a2167 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -272,6 +272,15 @@ "contributions": [ "code" ] + }, + { + "login": "SrdjanPaunovic", + "name": "Srđan Paunović", + "avatar_url": "https://avatars1.githubusercontent.com/u/22815104?v=4", + "profile": "https://github.com/SrdjanPaunovic", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 3ec2bcbab..514df2349 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-29-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-30-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -106,6 +106,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻 +
Srđan Paunović

💻 From d94199f5fff6cf83604d3aaa8b2b130315e2f5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 18:23:47 +0300 Subject: [PATCH 065/285] update readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 514df2349..eafae6ef5 100644 --- a/README.md +++ b/README.md @@ -113,5 +113,3 @@ This project is licensed under the terms of the MIT license. - -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! From 0bc3756250ef110a1c6adfd910cc1ecf0ededefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 18:49:46 +0300 Subject: [PATCH 066/285] update all-contributors config --- .all-contributorsrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7c71a2167..bdd7dfdaa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -283,7 +283,7 @@ ] } ], - "contributorsPerLine": 7, + "contributorsPerLine": 4, "projectName": "java-design-patterns", "projectOwner": "iluwatar", "repoType": "github", From 96344142e9064e5afd08c3c8450b38419ca3528b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 18:52:31 +0300 Subject: [PATCH 067/285] docs: add sideris as a contributor (#1375) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bdd7dfdaa..1d6b1aabc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -281,6 +281,15 @@ "contributions": [ "code" ] + }, + { + "login": "sideris", + "name": "Petros G. Sideris", + "avatar_url": "https://avatars3.githubusercontent.com/u/5484694?v=4", + "profile": "https://sideris.xyz/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index eafae6ef5..55e167ef8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-30-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -73,32 +73,38 @@ This project is licensed under the terms of the MIT license.
amit1307

💻
Narendra Pathai

💻 🤔 👀
Jeroen Meulemeester

💻 + +
Joseph McCarthy

💻
Thomas

💻
Anurag Agarwal

💻 +
Markus Moser

🎨 💻 🤔 -
Markus Moser

🎨 💻 🤔
Sabiq Ihab

💻
Amit Dixit

💻
Piyush Kailash Chaudhari

💻
joshzambales

💻 -
Kamil Pietruszka

💻 -
Zafar Khaydarov

💻 📖 +
Kamil Pietruszka

💻 +
Zafar Khaydarov

💻 📖
Paul Campbell

💻
Argyro Sioziou

💻 + +
TylerMcConville

💻
saksham93

💻
nikhilbarar

💻
Colin But

💻 -
Ruslan

💻 +
Ruslan

💻
Juho Kang

💻
Dheeraj Mummareddy

💻
Bernardo Sulzbach

💻 + +
Aleksandar Dudukovic

💻
Yusuf Aytaş

💻
Mihály Kuprivecz

💻 @@ -107,6 +113,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻 +
Petros G. Sideris

💻 From c0d2c7fdb04a239488db9457197d095173fc1b79 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:23:30 +0300 Subject: [PATCH 068/285] docs: add robertt240 as a contributor (#1376) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1d6b1aabc..f5238558b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -290,6 +290,15 @@ "contributions": [ "code" ] + }, + { + "login": "robertt240", + "name": "Robert Kasperczyk", + "avatar_url": "https://avatars1.githubusercontent.com/u/9137432?v=4", + "profile": "https://github.com/robertt240", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 55e167ef8..026ba94e3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-31-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Robert Kasperczyk

💻 From cfba28f9a4a0017d22506a7655e97c648413a79b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:33:05 +0300 Subject: [PATCH 069/285] docs: add okinskas as a contributor (#1377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f5238558b..9780bbbf8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "okinskas", + "name": "Ovidijus Okinskas", + "avatar_url": "https://avatars0.githubusercontent.com/u/20372387?v=4", + "profile": "https://www.linkedin.com/in/ovidijus-okinskas/", + "contributions": [ + "code" + ] + }, { "login": "robertt240", "name": "Robert Kasperczyk", diff --git a/README.md b/README.md index 026ba94e3..4e931dca2 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From 2b095bec283932368a7111463ae0082836c0afdf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:37:11 +0300 Subject: [PATCH 070/285] docs: add ankurkaushal as a contributor (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9780bbbf8..724d5e0d7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ankurkaushal", + "name": "Ankur Kaushal", + "avatar_url": "https://avatars2.githubusercontent.com/u/2236616?v=4", + "profile": "https://github.com/ankurkaushal", + "contributions": [ + "code" + ] + }, { "login": "okinskas", "name": "Ovidijus Okinskas", diff --git a/README.md b/README.md index 4e931dca2..7e71b1e62 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Ankur Kaushal

💻
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From f85e4db0bed8b96864375028d90ee31bf05f9ccc Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:40:11 +0300 Subject: [PATCH 071/285] docs: add Tschis as a contributor (#1379) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 724d5e0d7..cfc3cdfc5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Tschis", + "name": "Rodolfo Forte", + "avatar_url": "https://avatars1.githubusercontent.com/u/20662669?v=4", + "profile": "http://tschis.github.io", + "contributions": [ + "content" + ] + }, { "login": "ankurkaushal", "name": "Ankur Kaushal", diff --git a/README.md b/README.md index 7e71b1e62..506948ca9 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻
Robert Kasperczyk

💻 From 60ab9fa3ceb61e63acf8267507a502a8433ded70 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:43:09 +0300 Subject: [PATCH 072/285] docs: add qza as a contributor (#1380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index cfc3cdfc5..9b817c42d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "qza", + "name": "qza", + "avatar_url": "https://avatars3.githubusercontent.com/u/233149?v=4", + "profile": "https://github.com/qza", + "contributions": [ + "code" + ] + }, { "login": "Tschis", "name": "Rodolfo Forte", diff --git a/README.md b/README.md index 506948ca9..ad0a2fa5d 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻 From 023865ad4c5b63f85bf1b6d001636543ff354f0e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2020 20:45:59 +0300 Subject: [PATCH 073/285] docs: add pitsios-s as a contributor (#1381) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9b817c42d..df2e3e857 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "pitsios-s", + "name": "Stamatis Pitsios", + "avatar_url": "https://avatars1.githubusercontent.com/u/6773603?v=4", + "profile": "https://twitter.com/StPitsios", + "contributions": [ + "code" + ] + }, { "login": "qza", "name": "qza", diff --git a/README.md b/README.md index ad0a2fa5d..94615bf9c 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 +
Stamatis Pitsios

💻
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻 From 0358fcec4c1f35c84d631e214c81bb6b96e2c74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 28 Jul 2020 20:53:31 +0300 Subject: [PATCH 074/285] update readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 94615bf9c..97e3111cf 100644 --- a/README.md +++ b/README.md @@ -115,10 +115,14 @@ This project is licensed under the terms of the MIT license.
Srđan Paunović

💻
Petros G. Sideris

💻
Stamatis Pitsios

💻 + +
qza

💻
Rodolfo Forte

🖋
Ankur Kaushal

💻
Ovidijus Okinskas

💻 + +
Robert Kasperczyk

💻 From eb8ddde98ffd9d63dce24ddd8f76a00649520889 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:36:32 +0300 Subject: [PATCH 075/285] docs: add llitfkitfk as a contributor (#1382) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index df2e3e857..3d7e4065e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "llitfkitfk", + "name": "田浩", + "avatar_url": "https://avatars1.githubusercontent.com/u/2404785?v=4", + "profile": "https://t.me/paul_docker", + "contributions": [ + "content" + ] + }, { "login": "pitsios-s", "name": "Stamatis Pitsios", diff --git a/README.md b/README.md index 97e3111cf..79f9b34ff 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Stamatis Pitsios

💻 +
田浩

🖋
qza

💻 @@ -123,6 +123,7 @@ This project is licensed under the terms of the MIT license.
Ovidijus Okinskas

💻 +
Stamatis Pitsios

💻
Robert Kasperczyk

💻 From 8d6791490b63dbbfab8c093378c730eeee805bcd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:39:11 +0300 Subject: [PATCH 076/285] docs: add gwildor28 as a contributor (#1383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3d7e4065e..f37d603e5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "gwildor28", + "name": "gwildor28", + "avatar_url": "https://avatars0.githubusercontent.com/u/16000365?v=4", + "profile": "https://github.com/gwildor28", + "contributions": [ + "content" + ] + }, { "login": "llitfkitfk", "name": "田浩", diff --git a/README.md b/README.md index 79f9b34ff..104d7afa2 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
田浩

🖋 +
gwildor28

💻
qza

💻 @@ -125,6 +125,7 @@ This project is licensed under the terms of the MIT license.
Stamatis Pitsios

💻
Robert Kasperczyk

💻 +
田浩

🖋 From 39e5436ed5ed13c1ff81487a08cd5b2d30eca0a5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:41:35 +0300 Subject: [PATCH 077/285] docs: add amit2103 as a contributor (#1384) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f37d603e5..c9c27ed6b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "amit2103", + "name": "Amit Pandey", + "avatar_url": "https://avatars3.githubusercontent.com/u/7566692?v=4", + "profile": "https://github.com/amit2103", + "contributions": [ + "code" + ] + }, { "login": "gwildor28", "name": "gwildor28", diff --git a/README.md b/README.md index 104d7afa2..1417b68d3 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
gwildor28

💻 +
Amit Pandey

💻
qza

💻 @@ -126,6 +126,7 @@ This project is licensed under the terms of the MIT license.
Stamatis Pitsios

💻
Robert Kasperczyk

💻
田浩

🖋 +
gwildor28

💻 From 81824057968557335d4812093ddc70ec7c12e73c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:44:05 +0300 Subject: [PATCH 078/285] docs: add hoswey as a contributor (#1385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c9c27ed6b..ef533e802 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hoswey", + "name": "Hoswey", + "avatar_url": "https://avatars3.githubusercontent.com/u/3689445?v=4", + "profile": "https://github.com/hoswey", + "contributions": [ + "code" + ] + }, { "login": "amit2103", "name": "Amit Pandey", diff --git a/README.md b/README.md index 1417b68d3..e9cb72003 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Amit Pandey

💻 +
Hoswey

💻
qza

💻 @@ -128,6 +128,9 @@ This project is licensed under the terms of the MIT license.
田浩

🖋
gwildor28

💻 + +
Amit Pandey

💻 + From 37bffb4a99865f4ca34a4d4ac6816a52e8b79b9f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:47:06 +0300 Subject: [PATCH 079/285] docs: add gopinath-langote as a contributor (#1386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ef533e802..21d993c64 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "gopinath-langote", + "name": "Gopinath Langote", + "avatar_url": "https://avatars2.githubusercontent.com/u/10210778?v=4", + "profile": "https://www.linkedin.com/in/gopinathlangote/", + "contributions": [ + "code" + ] + }, { "login": "hoswey", "name": "Hoswey", diff --git a/README.md b/README.md index e9cb72003..d9fba1e99 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hoswey

💻 +
Gopinath Langote

💻
qza

💻 @@ -130,6 +130,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻 +
Hoswey

💻 From 8c21809dad7caf2d42d19e32c1eead5c6fc6de8e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:49:00 +0300 Subject: [PATCH 080/285] docs: add ThatGuyWithTheHat as a contributor (#1387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 21d993c64..edef8c2c5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ThatGuyWithTheHat", + "name": "Matt", + "avatar_url": "https://avatars0.githubusercontent.com/u/24470582?v=4", + "profile": "https://github.com/ThatGuyWithTheHat", + "contributions": [ + "content" + ] + }, { "login": "gopinath-langote", "name": "Gopinath Langote", diff --git a/README.md b/README.md index d9fba1e99..5d9b81ca7 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Gopinath Langote

💻 +
Matt

🖋
qza

💻 @@ -131,6 +131,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻
Hoswey

💻 +
Gopinath Langote

💻 From 5a23fab795d1588a2cada9e923eb8856ff2398a0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:50:53 +0300 Subject: [PATCH 081/285] docs: add vehpsr as a contributor (#1389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index edef8c2c5..e1b8032cb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "vehpsr", + "name": "gans", + "avatar_url": "https://avatars2.githubusercontent.com/u/3133265?v=4", + "profile": "https://github.com/vehpsr", + "contributions": [ + "code" + ] + }, { "login": "ThatGuyWithTheHat", "name": "Matt", diff --git a/README.md b/README.md index 5d9b81ca7..62c70ae2f 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Matt

🖋 +
gans

💻
qza

💻 @@ -132,6 +132,7 @@ This project is licensed under the terms of the MIT license.
Amit Pandey

💻
Hoswey

💻
Gopinath Langote

💻 +
Matt

🖋 From c0d7c8922e82eb02cbeff2b331dc8b1ed30924b8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:53:30 +0300 Subject: [PATCH 082/285] docs: add Azureyjt as a contributor (#1388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e1b8032cb..7a1681230 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Azureyjt", + "name": "Azureyjt", + "avatar_url": "https://avatars2.githubusercontent.com/u/18476317?v=4", + "profile": "https://github.com/Azureyjt", + "contributions": [ + "code" + ] + }, { "login": "vehpsr", "name": "gans", diff --git a/README.md b/README.md index 62c70ae2f..6b90e2df8 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
gans

💻 +
Azureyjt

💻
qza

💻 @@ -134,6 +134,9 @@ This project is licensed under the terms of the MIT license.
Gopinath Langote

💻
Matt

🖋 + +
gans

💻 + From 7968615ad466c86b9d68cd25eee5d9a53a27f682 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:55:53 +0300 Subject: [PATCH 083/285] docs: add mookkiah as a contributor (#1390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7a1681230..ec24b3888 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "mookkiah", + "name": "Mahendran Mookkiah", + "avatar_url": "https://avatars1.githubusercontent.com/u/8975264?v=4", + "profile": "https://github.com/mookkiah", + "contributions": [ + "code" + ] + }, { "login": "Azureyjt", "name": "Azureyjt", diff --git a/README.md b/README.md index 6b90e2df8..ac8ab189a 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Azureyjt

💻 +
Mahendran Mookkiah

💻
qza

💻 @@ -136,6 +136,7 @@ This project is licensed under the terms of the MIT license.
gans

💻 +
Azureyjt

💻 From c5479cc882d3a1ff8c52fedd8ec8d6371bb64368 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:58:00 +0300 Subject: [PATCH 084/285] docs: add llorllale as a contributor (#1391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ec24b3888..02b8d2f37 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "llorllale", + "name": "George Aristy", + "avatar_url": "https://avatars1.githubusercontent.com/u/2019896?v=4", + "profile": "https://llorllale.github.io/", + "contributions": [ + "code" + ] + }, { "login": "mookkiah", "name": "Mahendran Mookkiah", diff --git a/README.md b/README.md index ac8ab189a..8869d6e26 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Mahendran Mookkiah

💻 +
George Aristy

💻
qza

💻 @@ -137,6 +137,7 @@ This project is licensed under the terms of the MIT license.
gans

💻
Azureyjt

💻 +
Mahendran Mookkiah

💻 From c2fb5917496f001fc4293e2a4f7beb3a2af5542c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:00:07 +0300 Subject: [PATCH 085/285] docs: add igeligel as a contributor (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 02b8d2f37..71677e31f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "igeligel", + "name": "Kevin Peters", + "avatar_url": "https://avatars1.githubusercontent.com/u/12736734?v=4", + "profile": "https://www.kevinpeters.net/about/", + "contributions": [ + "code" + ] + }, { "login": "llorllale", "name": "George Aristy", diff --git a/README.md b/README.md index 8869d6e26..f8d66532b 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
George Aristy

💻 +
Kevin Peters

💻
qza

💻 @@ -138,6 +138,7 @@ This project is licensed under the terms of the MIT license.
gans

💻
Azureyjt

💻
Mahendran Mookkiah

💻 +
George Aristy

💻 From d1de4657801a2f4715673f79102cbf181e89e819 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:02:13 +0300 Subject: [PATCH 086/285] docs: add hbothra15 as a contributor (#1393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 71677e31f..c7cef5bea 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hbothra15", + "name": "Hemant Bothra", + "avatar_url": "https://avatars1.githubusercontent.com/u/7418012?v=4", + "profile": "https://github.com/hbothra15", + "contributions": [ + "code" + ] + }, { "login": "igeligel", "name": "Kevin Peters", diff --git a/README.md b/README.md index f8d66532b..1b57fa8ab 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Kevin Peters

💻 +
Hemant Bothra

💻
qza

💻 @@ -140,6 +140,9 @@ This project is licensed under the terms of the MIT license.
Mahendran Mookkiah

💻
George Aristy

💻 + +
Kevin Peters

💻 + From ec80402fe50b81cc651946a48c7aa0b0f5b9e224 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:05:22 +0300 Subject: [PATCH 087/285] docs: add giorgosmav21 as a contributor (#1394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7cef5bea..9518ede79 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "giorgosmav21", + "name": "George Mavroeidis", + "avatar_url": "https://avatars2.githubusercontent.com/u/22855493?v=4", + "profile": "https://github.com/giorgosmav21", + "contributions": [ + "code" + ] + }, { "login": "hbothra15", "name": "Hemant Bothra", diff --git a/README.md b/README.md index 1b57fa8ab..12ba1a7e4 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hemant Bothra

💻 +
George Mavroeidis

💻
qza

💻 @@ -142,6 +142,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻 +
Hemant Bothra

💻 From be54dc1c7e24e71d6fdae7069811e6eddf4f06c5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:07:15 +0300 Subject: [PATCH 088/285] docs: add oconnelc as a contributor (#1395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9518ede79..25192ed78 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "oconnelc", + "name": "Christopher O'Connell", + "avatar_url": "https://avatars0.githubusercontent.com/u/1112973?v=4", + "profile": "https://github.com/oconnelc", + "contributions": [ + "code" + ] + }, { "login": "giorgosmav21", "name": "George Mavroeidis", diff --git a/README.md b/README.md index 12ba1a7e4..d1cbd2f1c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
George Mavroeidis

💻 +
Christopher O'Connell

💻
qza

💻 @@ -143,6 +143,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻
Hemant Bothra

💻 +
George Mavroeidis

💻 From ba485e2c3efb6669cece11164f93fb9bd4186316 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:09:00 +0300 Subject: [PATCH 089/285] docs: add npczwh as a contributor (#1396) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 25192ed78..17c9bc3d6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "npczwh", + "name": "Zhang WH", + "avatar_url": "https://avatars0.githubusercontent.com/u/14066422?v=4", + "profile": "https://github.com/npczwh", + "contributions": [ + "code" + ] + }, { "login": "oconnelc", "name": "Christopher O'Connell", diff --git a/README.md b/README.md index d1cbd2f1c..227c62c60 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Christopher O'Connell

💻 +
Zhang WH

💻
qza

💻 @@ -144,6 +144,7 @@ This project is licensed under the terms of the MIT license.
Kevin Peters

💻
Hemant Bothra

💻
George Mavroeidis

💻 +
Christopher O'Connell

💻 From d791c785014b200b38c95d07859cabf9f8a16b8b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:11:09 +0300 Subject: [PATCH 090/285] docs: add leogtzr as a contributor (#1397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 17c9bc3d6..985bd474f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "leogtzr", + "name": "Leo Gutiérrez Ramírez", + "avatar_url": "https://avatars0.githubusercontent.com/u/1211969?v=4", + "profile": "https://github.com/leogtzr", + "contributions": [ + "code" + ] + }, { "login": "npczwh", "name": "Zhang WH", diff --git a/README.md b/README.md index 227c62c60..7e2ffc3d3 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,9 @@ This project is licensed under the terms of the MIT license.
George Mavroeidis

💻
Christopher O'Connell

💻 + +
Leo Gutiérrez Ramírez

💻 + From e924c9399ad236da1db94edd049147a3975fa007 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:12:47 +0300 Subject: [PATCH 091/285] docs: add hannespernpeintner as a contributor (#1398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 985bd474f..69a4de8f3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hannespernpeintner", + "name": "Hannes", + "avatar_url": "https://avatars3.githubusercontent.com/u/1679437?v=4", + "profile": "https://bitbucket.org/hannespernpeintner/", + "contributions": [ + "code" + ] + }, { "login": "leogtzr", "name": "Leo Gutiérrez Ramírez", diff --git a/README.md b/README.md index 7e2ffc3d3..9ceb86f80 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻 +
Hannes

💻 From 8137609e2f4a3ff7a9d43615c2707f634d699f70 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:14:30 +0300 Subject: [PATCH 092/285] docs: add dgruntz as a contributor (#1399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 69a4de8f3..c36df4855 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dgruntz", + "name": "Dominik Gruntz", + "avatar_url": "https://avatars0.githubusercontent.com/u/1516800?v=4", + "profile": "https://github.com/dgruntz", + "contributions": [ + "code" + ] + }, { "login": "hannespernpeintner", "name": "Hannes", diff --git a/README.md b/README.md index 9ceb86f80..fef0bf614 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻
Hannes

💻 +
Dominik Gruntz

💻 From 46fdc5a54f0b4ec741f4dae395acf5d9ffe35eaf Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:16:12 +0300 Subject: [PATCH 093/285] docs: add christofferh as a contributor (#1400) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c36df4855..8e0e6d13a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "christofferh", + "name": "Christoffer Hamberg", + "avatar_url": "https://avatars1.githubusercontent.com/u/767643?v=4", + "profile": "https://christofferh.com", + "contributions": [ + "code" + ] + }, { "login": "dgruntz", "name": "Dominik Gruntz", diff --git a/README.md b/README.md index fef0bf614..9720fbad5 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ This project is licensed under the terms of the MIT license.
Leo Gutiérrez Ramírez

💻
Hannes

💻
Dominik Gruntz

💻 +
Christoffer Hamberg

💻 From a727a1d05b79b17ca2dd1a926d67cf8e651dcc52 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:18:07 +0300 Subject: [PATCH 094/285] docs: add AnaghaSasikumar as a contributor (#1401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8e0e6d13a..ca442aa6e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "AnaghaSasikumar", + "name": "AnaghaSasikumar", + "avatar_url": "https://avatars2.githubusercontent.com/u/42939261?v=4", + "profile": "https://github.com/AnaghaSasikumar", + "contributions": [ + "code" + ] + }, { "login": "christofferh", "name": "Christoffer Hamberg", diff --git a/README.md b/README.md index 9720fbad5..508a1dbef 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,9 @@ This project is licensed under the terms of the MIT license.
Dominik Gruntz

💻
Christoffer Hamberg

💻 + +
AnaghaSasikumar

💻 + From 96bfb8bd9f1c293634828c0fd8e5ef074a4821f8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:19:53 +0300 Subject: [PATCH 095/285] docs: add waisuan as a contributor (#1402) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ca442aa6e..94158246d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "waisuan", + "name": "Evan Sia Wai Suan", + "avatar_url": "https://avatars2.githubusercontent.com/u/10975700?v=4", + "profile": "https://github.com/waisuan", + "contributions": [ + "code" + ] + }, { "login": "AnaghaSasikumar", "name": "AnaghaSasikumar", diff --git a/README.md b/README.md index 508a1dbef..6a091ea20 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻 +
Evan Sia Wai Suan

💻 From 09880e3850277b372975089725a7d3cdf8754a37 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:21:41 +0300 Subject: [PATCH 096/285] docs: add perwramdemark as a contributor (#1403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 94158246d..a2cfd2a03 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "perwramdemark", + "name": "Per Wramdemark", + "avatar_url": "https://avatars2.githubusercontent.com/u/7052193?v=4", + "profile": "http://www.wramdemark.se", + "contributions": [ + "code" + ] + }, { "login": "waisuan", "name": "Evan Sia Wai Suan", diff --git a/README.md b/README.md index 6a091ea20..51c774275 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻
Evan Sia Wai Suan

💻 +
Per Wramdemark

💻 From 19929d9e7215223eddc03b5f1e950b7ec164297d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:23:23 +0300 Subject: [PATCH 097/285] docs: add leonmak as a contributor (#1404) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index a2cfd2a03..fa19cf391 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "leonmak", + "name": "Leon Mak", + "avatar_url": "https://avatars3.githubusercontent.com/u/13071508?v=4", + "profile": "http://leonmak.me", + "contributions": [ + "code" + ] + }, { "login": "perwramdemark", "name": "Per Wramdemark", diff --git a/README.md b/README.md index 51c774275..abea00951 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,9 @@ This project is licensed under the terms of the MIT license.
AnaghaSasikumar

💻
Evan Sia Wai Suan

💻
Per Wramdemark

💻 +
Leon Mak

💻 + + From a70213f8521cadab757ed874183e7d4c43e6ac50 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:25:03 +0300 Subject: [PATCH 098/285] docs: add kanwarpreet25 as a contributor (#1405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fa19cf391..7b91a7aa5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kanwarpreet25", + "name": "kanwarpreet25", + "avatar_url": "https://avatars0.githubusercontent.com/u/39183641?v=4", + "profile": "https://github.com/kanwarpreet25", + "contributions": [ + "code" + ] + }, { "login": "leonmak", "name": "Leon Mak", diff --git a/README.md b/README.md index abea00951..53f0fedbb 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ This project is licensed under the terms of the MIT license.
Leon Mak

💻 +
kanwarpreet25

💻 From 54bb02f69131cccd0b6655e19de3df3e314e6ea8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:26:34 +0300 Subject: [PATCH 099/285] docs: add MSaifAsif as a contributor (#1406) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7b91a7aa5..1fadb0530 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "MSaifAsif", + "name": "M Saif Asif", + "avatar_url": "https://avatars1.githubusercontent.com/u/6280554?v=4", + "profile": "https://github.com/MSaifAsif", + "contributions": [ + "code" + ] + }, { "login": "kanwarpreet25", "name": "kanwarpreet25", diff --git a/README.md b/README.md index 53f0fedbb..708a62ca6 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻 +
M Saif Asif

💻 From e2a42b0051f4818908936aee5627329e1309cbfe Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:28:10 +0300 Subject: [PATCH 100/285] docs: add Alwayswithme as a contributor (#1407) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1fadb0530..782955f0c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Alwayswithme", + "name": "PhoenixYip", + "avatar_url": "https://avatars3.githubusercontent.com/u/3234786?v=4", + "profile": "https://alwayswithme.github.io", + "contributions": [ + "code" + ] + }, { "login": "MSaifAsif", "name": "M Saif Asif", diff --git a/README.md b/README.md index 708a62ca6..173485073 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻
M Saif Asif

💻 +
PhoenixYip

💻 From fe2f8f74a1d1126d5de4e3fa5c598038ec9b7a8d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:29:41 +0300 Subject: [PATCH 101/285] docs: add ranjeet-floyd as a contributor (#1408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 782955f0c..27e8872d7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "ranjeet-floyd", + "name": "Ranjeet", + "avatar_url": "https://avatars0.githubusercontent.com/u/1992972?v=4", + "profile": "https://ranjeet-floyd.github.io", + "contributions": [ + "code" + ] + }, { "login": "Alwayswithme", "name": "PhoenixYip", diff --git a/README.md b/README.md index 173485073..46a1443e7 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ This project is licensed under the terms of the MIT license.
kanwarpreet25

💻
M Saif Asif

💻
PhoenixYip

💻 +
Ranjeet

💻 From 8e268cf261cd23f5de815f32da2d9c2b417d5c1a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:32:59 +0300 Subject: [PATCH 102/285] docs: add mitchellirvin as a contributor (#1409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 27e8872d7..4b9a0dd1a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "mitchellirvin", + "name": "Mitchell Irvin", + "avatar_url": "https://avatars0.githubusercontent.com/u/16233245?v=4", + "profile": "http://mitchell-irvin.com", + "contributions": [ + "code" + ] + }, { "login": "ranjeet-floyd", "name": "Ranjeet", diff --git a/README.md b/README.md index 46a1443e7..d587771d1 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,17 @@ This project is licensed under the terms of the MIT license.
PhoenixYip

💻
Ranjeet

💻 +
Mitchell Irvin

💻 + + + + + + + + + + From 9b5ae765fccfaac7be5fec221a48b0f0dde9ad54 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:34:45 +0300 Subject: [PATCH 103/285] docs: add kirill-vlasov as a contributor (#1410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4b9a0dd1a..6d3a4741f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kirill-vlasov", + "name": "Kirill Vlasov", + "avatar_url": "https://avatars3.githubusercontent.com/u/16112495?v=4", + "profile": "https://github.com/kirill-vlasov", + "contributions": [ + "code" + ] + }, { "login": "mitchellirvin", "name": "Mitchell Irvin", diff --git a/README.md b/README.md index d587771d1..f12fcb9ab 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻 +
Kirill Vlasov

💻 From 1bc77a80f2b8fcafc52e611af600f9a77d77c744 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:36:27 +0300 Subject: [PATCH 104/285] docs: add joningiwork as a contributor (#1411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6d3a4741f..7352e906e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "joningiwork", + "name": "Jón Ingi Sveinbjörnsson", + "avatar_url": "https://avatars2.githubusercontent.com/u/6115148?v=4", + "profile": "http://joningi.net", + "contributions": [ + "code" + ] + }, { "login": "kirill-vlasov", "name": "Kirill Vlasov", diff --git a/README.md b/README.md index f12fcb9ab..655c71e26 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Kirill Vlasov

💻 +
Jón Ingi Sveinbjörnsson

💻 From a475df845bf44163ce49c9289371d08436d27bb5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:38:07 +0300 Subject: [PATCH 105/285] docs: add jarpit96 as a contributor (#1412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7352e906e..ffe698d84 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "jarpit96", + "name": "Arpit Jain", + "avatar_url": "https://avatars2.githubusercontent.com/u/10098713?v=4", + "profile": "https://github.com/jarpit96", + "contributions": [ + "code" + ] + }, { "login": "joningiwork", "name": "Jón Ingi Sveinbjörnsson", diff --git a/README.md b/README.md index 655c71e26..c59bfac02 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,7 @@ This project is licensed under the terms of the MIT license.
Ranjeet

💻
Mitchell Irvin

💻 +
Arpit Jain

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From 2a66fec6fe509a2b3a96d086d3e7265aebf823b1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:41:17 +0300 Subject: [PATCH 106/285] docs: add hoangnam2261 as a contributor (#1413) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ffe698d84..ca9e4c8e0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "hoangnam2261", + "name": "hoangnam2261", + "avatar_url": "https://avatars2.githubusercontent.com/u/31692990?v=4", + "profile": "https://github.com/hoangnam2261", + "contributions": [ + "code" + ] + }, { "login": "jarpit96", "name": "Arpit Jain", diff --git a/README.md b/README.md index c59bfac02..b10ea2a59 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Arpit Jain

💻 +
hoangnam2261

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From d11b2f06ea91219a2952ca0ea578faef13384ab8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:42:55 +0300 Subject: [PATCH 107/285] docs: add fanofxiaofeng as a contributor (#1414) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ca9e4c8e0..76018eb5a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "fanofxiaofeng", + "name": "靳阳", + "avatar_url": "https://avatars0.githubusercontent.com/u/3983683?v=4", + "profile": "https://github.com/fanofxiaofeng", + "contributions": [ + "code" + ] + }, { "login": "hoangnam2261", "name": "hoangnam2261", diff --git a/README.md b/README.md index b10ea2a59..9d2c2fb91 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ This project is licensed under the terms of the MIT license.
Mitchell Irvin

💻
Arpit Jain

💻
hoangnam2261

💻 +
靳阳

💻
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 From 1bbae5fd5a63a6c56e4b576ce4b6cd0abbc59855 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:44:29 +0300 Subject: [PATCH 108/285] docs: add dmitraver as a contributor (#1415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 76018eb5a..c04339058 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dmitraver", + "name": "Dmitry Avershin", + "avatar_url": "https://avatars3.githubusercontent.com/u/1798156?v=4", + "profile": "https://github.com/dmitraver", + "contributions": [ + "code" + ] + }, { "login": "fanofxiaofeng", "name": "靳阳", diff --git a/README.md b/README.md index 9d2c2fb91..04721d214 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,7 @@ This project is licensed under the terms of the MIT license.
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 +
Dmitry Avershin

💻 From b67a019c48c185e824acf3936b917a0b06764715 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:45:53 +0300 Subject: [PATCH 109/285] docs: add besok as a contributor (#1416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c04339058..f30ec4f26 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "besok", + "name": "Boris", + "avatar_url": "https://avatars2.githubusercontent.com/u/29834592?v=4", + "profile": "https://github.com/besok", + "contributions": [ + "code" + ] + }, { "login": "dmitraver", "name": "Dmitry Avershin", diff --git a/README.md b/README.md index 04721d214..4407d4f36 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ This project is licensed under the terms of the MIT license.
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻
Dmitry Avershin

💻 +
Boris

💻 From b4e4cf9cfe4633ebc35e0f91836ce20bd671e11c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:48:09 +0300 Subject: [PATCH 110/285] docs: add baislsl as a contributor (#1417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f30ec4f26..39babdca5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "baislsl", + "name": "Shengli Bai", + "avatar_url": "https://avatars0.githubusercontent.com/u/17060584?v=4", + "profile": "https://github.com/baislsl", + "contributions": [ + "code" + ] + }, { "login": "besok", "name": "Boris", diff --git a/README.md b/README.md index 4407d4f36..cc5d3a99e 100644 --- a/README.md +++ b/README.md @@ -164,10 +164,12 @@ This project is licensed under the terms of the MIT license.
PhoenixYip

💻
Ranjeet

💻 +
Mitchell Irvin

💻
Arpit Jain

💻
hoangnam2261

💻
靳阳

💻 +
Kirill Vlasov

💻
Jón Ingi Sveinbjörnsson

💻 @@ -175,6 +177,7 @@ This project is licensed under the terms of the MIT license.
Boris

💻 +
Shengli Bai

💻 From 65d627b2ed11a5d8fdbeae32266bf2cf3dbfcdd8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 18:49:46 +0300 Subject: [PATCH 111/285] docs: add akrystian as a contributor (#1418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 39babdca5..92b26c57e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "akrystian", + "name": "adamski.pro", + "avatar_url": "https://avatars1.githubusercontent.com/u/6537430?v=4", + "profile": "http://adamski.pro", + "contributions": [ + "code" + ] + }, { "login": "baislsl", "name": "Shengli Bai", diff --git a/README.md b/README.md index cc5d3a99e..0d91ed28f 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻 +
adamski.pro

💻 From 47acedaaf7e733d131df78126c3968df40ad4072 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:10:44 +0300 Subject: [PATCH 112/285] docs: add Rzeposlaw as a contributor (#1419) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 92b26c57e..8ff68a0b8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Rzeposlaw", + "name": "Katarzyna Rzepecka", + "avatar_url": "https://avatars2.githubusercontent.com/u/18425745?v=4", + "profile": "https://github.com/Rzeposlaw", + "contributions": [ + "code" + ] + }, { "login": "akrystian", "name": "adamski.pro", diff --git a/README.md b/README.md index 0d91ed28f..8e02e8749 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻
adamski.pro

💻 +
Katarzyna Rzepecka

💻 From ae57ec75f3dbe269113e40691d7fbab038735035 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:12:46 +0300 Subject: [PATCH 113/285] docs: add LuigiCortese as a contributor (#1420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8ff68a0b8..98f1a8eba 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "LuigiCortese", + "name": "Luigi Cortese", + "avatar_url": "https://avatars0.githubusercontent.com/u/9956006?v=4", + "profile": "http://www.devsedge.net/", + "contributions": [ + "code" + ] + }, { "login": "Rzeposlaw", "name": "Katarzyna Rzepecka", diff --git a/README.md b/README.md index 8e02e8749..182219262 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ This project is licensed under the terms of the MIT license.
Shengli Bai

💻
adamski.pro

💻
Katarzyna Rzepecka

💻 +
Luigi Cortese

💻 From efd8c8156e9f6ce3ab5714e971973ec35360d683 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:14:26 +0300 Subject: [PATCH 114/285] docs: add Juaanma as a contributor (#1421) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 98f1a8eba..df021acbe 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Juaanma", + "name": "Juan Manuel Suárez", + "avatar_url": "https://avatars3.githubusercontent.com/u/7390500?v=4", + "profile": "https://github.com/Juaanma", + "contributions": [ + "code" + ] + }, { "login": "LuigiCortese", "name": "Luigi Cortese", diff --git a/README.md b/README.md index 182219262..33df95b87 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ This project is licensed under the terms of the MIT license.
Luigi Cortese

💻 +
Juan Manuel Suárez

💻 From 325f0d93b24d9779109391cb7a5c876eaf048aa1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:16:02 +0300 Subject: [PATCH 115/285] docs: add 7agustibm as a contributor (#1422) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index df021acbe..c7d6637a9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "7agustibm", + "name": "Agustí Becerra Milà", + "avatar_url": "https://avatars0.githubusercontent.com/u/8149332?v=4", + "profile": "https://github.com/7agustibm", + "contributions": [ + "code" + ] + }, { "login": "Juaanma", "name": "Juan Manuel Suárez", diff --git a/README.md b/README.md index 33df95b87..c9429805b 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻 +
Agustí Becerra Milà

💻 From 1841fba8319af0e7a12a0ea04320311702b4b950 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:17:45 +0300 Subject: [PATCH 116/285] docs: add yosfik as a contributor (#1423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7d6637a9..1e49b8d91 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "yosfik", + "name": "Yosfik Alqadri", + "avatar_url": "https://avatars3.githubusercontent.com/u/4850270?v=4", + "profile": "https://github.com/yosfik", + "contributions": [ + "code" + ] + }, { "login": "7agustibm", "name": "Agustí Becerra Milà", diff --git a/README.md b/README.md index c9429805b..74c9220bc 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻
Agustí Becerra Milà

💻 +
Yosfik Alqadri

💻 From ecb7b44f970c3701ef04db47575f11078c45fa8c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:19:24 +0300 Subject: [PATCH 117/285] docs: add vanogrid as a contributor (#1424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1e49b8d91..8d9026820 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "vanogrid", + "name": "Alexander Ivanov", + "avatar_url": "https://avatars0.githubusercontent.com/u/4307918?v=4", + "profile": "https://www.vanogrid.com", + "contributions": [ + "code" + ] + }, { "login": "yosfik", "name": "Yosfik Alqadri", diff --git a/README.md b/README.md index 74c9220bc..13a649741 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ This project is licensed under the terms of the MIT license.
Juan Manuel Suárez

💻
Agustí Becerra Milà

💻
Yosfik Alqadri

💻 +
Alexander Ivanov

💻 From b5fac5cf861df4414dfb76f6b2560cb72f1c9be4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:21:22 +0300 Subject: [PATCH 118/285] docs: add valdar-hu as a contributor (#1425) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8d9026820..0087c240e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "valdar-hu", + "name": "Krisztián Nagy", + "avatar_url": "https://avatars3.githubusercontent.com/u/17962817?v=4", + "profile": "https://github.com/valdar-hu", + "contributions": [ + "code" + ] + }, { "login": "vanogrid", "name": "Alexander Ivanov", diff --git a/README.md b/README.md index 13a649741..4f2b4895c 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,7 @@ This project is licensed under the terms of the MIT license.
Alexander Ivanov

💻 +
Krisztián Nagy

💻 From 652a68b134838ed0f6d7a9fd2f4b29d0e1ad6961 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:23:12 +0300 Subject: [PATCH 119/285] docs: add staillebois as a contributor (#1426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0087c240e..fd2186072 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "staillebois", + "name": "staillebois", + "avatar_url": "https://avatars0.githubusercontent.com/u/23701200?v=4", + "profile": "https://github.com/staillebois", + "contributions": [ + "code" + ] + }, { "login": "valdar-hu", "name": "Krisztián Nagy", diff --git a/README.md b/README.md index 4f2b4895c..a93f15b13 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻 +
staillebois

💻 From 6f0035e7c23879b19eb514b2907fd392a55680c0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:25:03 +0300 Subject: [PATCH 120/285] docs: add sankypanhale as a contributor (#1427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fd2186072..511466186 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "sankypanhale", + "name": "Sanket Panhale", + "avatar_url": "https://avatars1.githubusercontent.com/u/6478783?v=4", + "profile": "https://github.com/sankypanhale", + "contributions": [ + "content" + ] + }, { "login": "staillebois", "name": "staillebois", diff --git a/README.md b/README.md index a93f15b13..911440c14 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻
staillebois

💻 +
Sanket Panhale

🖋 From dafe4956108c9602aed8bd241c80f3cef6247bd0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:26:38 +0300 Subject: [PATCH 121/285] docs: add prafful1 as a contributor (#1428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 511466186..591781b1c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "prafful1", + "name": "Prafful Agarwal", + "avatar_url": "https://avatars0.githubusercontent.com/u/14350274?v=4", + "profile": "https://github.com/prafful1", + "contributions": [ + "content" + ] + }, { "login": "sankypanhale", "name": "Sanket Panhale", diff --git a/README.md b/README.md index 911440c14..7ab4f2b78 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,7 @@ This project is licensed under the terms of the MIT license.
Krisztián Nagy

💻
staillebois

💻
Sanket Panhale

🖋 +
Prafful Agarwal

🖋 From 7fdcd2ec5ab7558ca29227d19acbade450f29cad Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:28:18 +0300 Subject: [PATCH 122/285] docs: add pnowy as a contributor (#1429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 591781b1c..9edfc2588 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "pnowy", + "name": "Przemek", + "avatar_url": "https://avatars1.githubusercontent.com/u/3254609?v=4", + "profile": "https://przemeknowak.com", + "contributions": [ + "code" + ] + }, { "login": "prafful1", "name": "Prafful Agarwal", diff --git a/README.md b/README.md index 7ab4f2b78..e159ca59f 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ This project is licensed under the terms of the MIT license.
Prafful Agarwal

🖋 +
Przemek

💻 From 6c9b912620f1ac84f6b7a61c486c8a400ee6d43d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:29:55 +0300 Subject: [PATCH 123/285] docs: add lbroman as a contributor (#1430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9edfc2588..3a9ed11ac 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "lbroman", + "name": "lbroman", + "avatar_url": "https://avatars1.githubusercontent.com/u/86007?v=4", + "profile": "https://github.com/lbroman", + "contributions": [ + "code" + ] + }, { "login": "pnowy", "name": "Przemek", diff --git a/README.md b/README.md index e159ca59f..03f77ef7d 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻 +
lbroman

💻 From 5d21a03acd97f13e8876686b936f5d48307f2c0a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:31:35 +0300 Subject: [PATCH 124/285] docs: add kaiwinter as a contributor (#1431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3a9ed11ac..ad0a07bff 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "kaiwinter", + "name": "Kai Winter", + "avatar_url": "https://avatars0.githubusercontent.com/u/110982?v=4", + "profile": "http://about.me/kaiwinter", + "contributions": [ + "code" + ] + }, { "login": "lbroman", "name": "lbroman", diff --git a/README.md b/README.md index 03f77ef7d..4a55b3c68 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻
lbroman

💻 +
Kai Winter

💻 From 1f900d164d3b697c29b2e26f17507495e2cd2367 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:33:18 +0300 Subject: [PATCH 125/285] docs: add jjjimenez100 as a contributor (#1432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index ad0a07bff..e7bc74009 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "jjjimenez100", + "name": "Joshua Jimenez", + "avatar_url": "https://avatars3.githubusercontent.com/u/22243493?v=4", + "profile": "https://github.com/jjjimenez100", + "contributions": [ + "code" + ] + }, { "login": "kaiwinter", "name": "Kai Winter", diff --git a/README.md b/README.md index 4a55b3c68..bbb11f58d 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ This project is licensed under the terms of the MIT license.
Przemek

💻
lbroman

💻
Kai Winter

💻 +
Joshua Jimenez

💻 From 73d55afd585106f169da9a3d3275714393073c90 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:34:58 +0300 Subject: [PATCH 126/285] docs: add dzmitryh as a contributor (#1433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index e7bc74009..9913c1e64 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "dzmitryh", + "name": "Dima Gubin", + "avatar_url": "https://avatars2.githubusercontent.com/u/5390492?v=4", + "profile": "https://about.me/dzmitryh", + "contributions": [ + "code" + ] + }, { "login": "jjjimenez100", "name": "Joshua Jimenez", diff --git a/README.md b/README.md index bbb11f58d..b0a836d2a 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,9 @@ This project is licensed under the terms of the MIT license.
Kai Winter

💻
Joshua Jimenez

💻 + +
Dima Gubin

💻 + From 9483888b5eb0fa1c4fe05ad15f0b19b9a6fed043 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:36:36 +0300 Subject: [PATCH 127/285] docs: add christophercolumbusdog as a contributor (#1434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9913c1e64..19119645d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "christophercolumbusdog", + "name": "Christian Cygnus", + "avatar_url": "https://avatars1.githubusercontent.com/u/9342724?v=4", + "profile": "http://ccygnus.com/", + "contributions": [ + "code" + ] + }, { "login": "dzmitryh", "name": "Dima Gubin", diff --git a/README.md b/README.md index b0a836d2a..c188513e2 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻 +
Christian Cygnus

💻 From e222a699648758ae29204ed699d17e809752653e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:38:23 +0300 Subject: [PATCH 128/285] docs: add anthonycampbell as a contributor (#1435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 19119645d..b9991fc22 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "anthonycampbell", + "name": "anthony", + "avatar_url": "https://avatars3.githubusercontent.com/u/10249255?v=4", + "profile": "https://github.com/anthonycampbell", + "contributions": [ + "code" + ] + }, { "login": "christophercolumbusdog", "name": "Christian Cygnus", diff --git a/README.md b/README.md index c188513e2..cdb66ef3b 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻
Christian Cygnus

💻 +
anthony

💻 From 706c5092c106420a1942a9d6a63db34b5fa133ab Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:40:00 +0300 Subject: [PATCH 129/285] docs: add amogozov as a contributor (#1436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index b9991fc22..385e4448c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "amogozov", + "name": "Artur Mogozov", + "avatar_url": "https://avatars3.githubusercontent.com/u/7372215?v=4", + "profile": "https://github.com/amogozov", + "contributions": [ + "code" + ] + }, { "login": "anthonycampbell", "name": "anthony", diff --git a/README.md b/README.md index cdb66ef3b..e213d97c0 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ This project is licensed under the terms of the MIT license.
Dima Gubin

💻
Christian Cygnus

💻
anthony

💻 +
Artur Mogozov

💻 From beffc87deb9a27b46f56fe91b3a69b6b52774fe3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:41:47 +0300 Subject: [PATCH 130/285] docs: add alexsomai as a contributor (#1437) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 385e4448c..dced8bd77 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "alexsomai", + "name": "Alexandru Somai", + "avatar_url": "https://avatars1.githubusercontent.com/u/5720977?v=4", + "profile": "https://alexsomai.com", + "contributions": [ + "code" + ] + }, { "login": "amogozov", "name": "Artur Mogozov", diff --git a/README.md b/README.md index e213d97c0..7405d01c4 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,9 @@ This project is licensed under the terms of the MIT license.
anthony

💻
Artur Mogozov

💻 + +
Alexandru Somai

💻 + From 62ac59afda52a62fca08c7c066d57eae62a8ea74 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:43:26 +0300 Subject: [PATCH 131/285] docs: add MaVdbussche as a contributor (#1438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index dced8bd77..c6400808a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "MaVdbussche", + "name": "Martin Vandenbussche", + "avatar_url": "https://avatars1.githubusercontent.com/u/26136934?v=4", + "profile": "https://github.com/MaVdbussche", + "contributions": [ + "code" + ] + }, { "login": "alexsomai", "name": "Alexandru Somai", diff --git a/README.md b/README.md index 7405d01c4..fef3b2712 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻 +
Martin Vandenbussche

💻 From 34a36cb519b7718d19eb06ed7b088b960f722e3c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:45:07 +0300 Subject: [PATCH 132/285] docs: add Harshrajsinh as a contributor (#1439) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index c6400808a..f694230e6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Harshrajsinh", + "name": "Harshraj Thakor", + "avatar_url": "https://avatars2.githubusercontent.com/u/22811531?v=4", + "profile": "https://github.com/Harshrajsinh", + "contributions": [ + "code" + ] + }, { "login": "MaVdbussche", "name": "Martin Vandenbussche", diff --git a/README.md b/README.md index fef3b2712..985605cd2 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻
Martin Vandenbussche

💻 +
Harshraj Thakor

💻 From 1d025b70193e361f39a73ed1faf7090f21c1ff16 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:47:29 +0300 Subject: [PATCH 133/285] docs: add Deathnerd as a contributor (#1440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f694230e6..7f925d4b8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Deathnerd", + "name": "Wes Gilleland", + "avatar_url": "https://avatars0.githubusercontent.com/u/1685953?v=4", + "profile": "http://theerroris.me", + "contributions": [ + "code" + ] + }, { "login": "Harshrajsinh", "name": "Harshraj Thakor", diff --git a/README.md b/README.md index 985605cd2..c879245d4 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ This project is licensed under the terms of the MIT license.
Alexandru Somai

💻
Martin Vandenbussche

💻
Harshraj Thakor

💻 +
Wes Gilleland

💻 From 87c2644842bfa5cbbbcd89ce0b2a4c1de3e4c76c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:49:20 +0300 Subject: [PATCH 134/285] docs: add Anurag870 as a contributor (#1441) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 3 +++ 2 files changed, 12 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7f925d4b8..60837ff7d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Anurag870", + "name": "Anurag870", + "avatar_url": "https://avatars1.githubusercontent.com/u/6295975?v=4", + "profile": "https://github.com/Anurag870", + "contributions": [ + "code" + ] + }, { "login": "Deathnerd", "name": "Wes Gilleland", diff --git a/README.md b/README.md index c879245d4..9f7e24500 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,9 @@ This project is licensed under the terms of the MIT license.
Harshraj Thakor

💻
Wes Gilleland

💻 + +
Anurag870

💻 + From a1b2ab129e6388cb8ac6fd4a10566fe347e8f49d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:51:03 +0300 Subject: [PATCH 135/285] docs: add Amarnath510 as a contributor (#1442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 60837ff7d..d2109eea0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "Amarnath510", + "name": "Amarnath Chandana", + "avatar_url": "https://avatars0.githubusercontent.com/u/4599623?v=4", + "profile": "https://amarnath510.github.io/portfolio", + "contributions": [ + "code" + ] + }, { "login": "Anurag870", "name": "Anurag870", diff --git a/README.md b/README.md index 9f7e24500..319a3760f 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,7 @@ This project is licensed under the terms of the MIT license.
Anurag870

💻 +
Amarnath Chandana

💻 From 69341ff7124debb5c114f680debf81a94da2cb65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:53:14 +0300 Subject: [PATCH 136/285] docs: add IAmPramod as a contributor (#1443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index d2109eea0..29549be77 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -291,6 +291,15 @@ "code" ] }, + { + "login": "IAmPramod", + "name": "Pramod Gupta", + "avatar_url": "https://avatars1.githubusercontent.com/u/2184241?v=4", + "profile": "https://www.linkedin.com/in/pramodgupta3/", + "contributions": [ + "review" + ] + }, { "login": "Amarnath510", "name": "Amarnath Chandana", diff --git a/README.md b/README.md index 319a3760f..8769e4a56 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ This project is licensed under the terms of the MIT license.
Anurag870

💻
Amarnath Chandana

💻 +
Pramod Gupta

👀 From 1f0a24cefa9f2c8c3036ccac64acbc8af67ad815 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 19:59:40 +0300 Subject: [PATCH 137/285] docs: add trautonen as a contributor (#1445) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++ README.md | 139 ++++++++++++++++++++++---------------------- 2 files changed, 79 insertions(+), 69 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 29549be77..57fed1a81 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -902,6 +902,15 @@ "contributions": [ "code" ] + }, + { + "login": "trautonen", + "name": "Tapio Rautonen", + "avatar_url": "https://avatars3.githubusercontent.com/u/1641063?v=4", + "profile": "https://github.com/trautonen", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 8769e4a56..b3c8f964d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-32-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-100-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,108 +114,109 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Zhang WH

💻 +
Pramod Gupta

👀 -
qza

💻 -
Rodolfo Forte

🖋 -
Ankur Kaushal

💻 -
Ovidijus Okinskas

💻 +
Amarnath Chandana

💻 +
Anurag870

💻 +
Wes Gilleland

💻 +
Harshraj Thakor

💻 -
Stamatis Pitsios

💻 -
Robert Kasperczyk

💻 -
田浩

🖋 -
gwildor28

💻 +
Martin Vandenbussche

💻 +
Alexandru Somai

💻 +
Artur Mogozov

💻 +
anthony

💻 -
Amit Pandey

💻 -
Hoswey

💻 -
Gopinath Langote

💻 -
Matt

🖋 +
Christian Cygnus

💻 +
Dima Gubin

💻 +
Joshua Jimenez

💻 +
Kai Winter

💻 -
gans

💻 -
Azureyjt

💻 -
Mahendran Mookkiah

💻 -
George Aristy

💻 +
lbroman

💻 +
Przemek

💻 +
Prafful Agarwal

🖋 +
Sanket Panhale

🖋 -
Kevin Peters

💻 -
Hemant Bothra

💻 -
George Mavroeidis

💻 -
Christopher O'Connell

💻 +
staillebois

💻 +
Krisztián Nagy

💻 +
Alexander Ivanov

💻 +
Yosfik Alqadri

💻 -
Leo Gutiérrez Ramírez

💻 -
Hannes

💻 -
Dominik Gruntz

💻 -
Christoffer Hamberg

💻 +
Agustí Becerra Milà

💻 +
Juan Manuel Suárez

💻 +
Luigi Cortese

💻 +
Katarzyna Rzepecka

💻 -
AnaghaSasikumar

💻 -
Evan Sia Wai Suan

💻 -
Per Wramdemark

💻 -
Leon Mak

💻 +
adamski.pro

💻 +
Shengli Bai

💻 +
Boris

💻 +
Dmitry Avershin

💻 -
kanwarpreet25

💻 -
M Saif Asif

💻 -
PhoenixYip

💻 -
Ranjeet

💻 - - -
Mitchell Irvin

💻 -
Arpit Jain

💻 -
hoangnam2261

💻
靳阳

💻 +
hoangnam2261

💻 +
Arpit Jain

💻 +
Jón Ingi Sveinbjörnsson

💻
Kirill Vlasov

💻 -
Jón Ingi Sveinbjörnsson

💻 -
Dmitry Avershin

💻 -
Boris

💻 +
Mitchell Irvin

💻 +
Ranjeet

💻 +
PhoenixYip

💻 -
Shengli Bai

💻 -
adamski.pro

💻 -
Katarzyna Rzepecka

💻 -
Luigi Cortese

💻 +
M Saif Asif

💻 +
kanwarpreet25

💻 +
Leon Mak

💻 +
Per Wramdemark

💻 -
Juan Manuel Suárez

💻 -
Agustí Becerra Milà

💻 -
Yosfik Alqadri

💻 -
Alexander Ivanov

💻 +
Evan Sia Wai Suan

💻 +
AnaghaSasikumar

💻 +
Christoffer Hamberg

💻 +
Dominik Gruntz

💻 -
Krisztián Nagy

💻 -
staillebois

💻 -
Sanket Panhale

🖋 -
Prafful Agarwal

🖋 +
Hannes

💻 +
Leo Gutiérrez Ramírez

💻 +
Zhang WH

💻 +
Christopher O'Connell

💻 -
Przemek

💻 -
lbroman

💻 -
Kai Winter

💻 -
Joshua Jimenez

💻 +
George Mavroeidis

💻 +
Hemant Bothra

💻 +
Kevin Peters

💻 +
George Aristy

💻 -
Dima Gubin

💻 -
Christian Cygnus

💻 -
anthony

💻 -
Artur Mogozov

💻 +
Mahendran Mookkiah

💻 +
Azureyjt

💻 +
gans

💻 +
Matt

🖋 -
Alexandru Somai

💻 -
Martin Vandenbussche

💻 -
Harshraj Thakor

💻 -
Wes Gilleland

💻 +
Gopinath Langote

💻 +
Hoswey

💻 +
Amit Pandey

💻 +
gwildor28

🖋 -
Anurag870

💻 -
Amarnath Chandana

💻 -
Pramod Gupta

👀 +
田浩

🖋 +
Stamatis Pitsios

💻 +
qza

💻 +
Rodolfo Forte

🖋 + + +
Ankur Kaushal

💻 +
Ovidijus Okinskas

💻 +
Robert Kasperczyk

💻 +
Tapio Rautonen

💻 From 075fbe74332aa7fec0a8420751d86ecca0bc79c0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:04:33 +0300 Subject: [PATCH 138/285] docs: add yorlov as a contributor (#1446) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 57fed1a81..0fb6f83cc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -911,6 +911,15 @@ "contributions": [ "code" ] + }, + { + "login": "yorlov", + "name": "Yuri Orlov", + "avatar_url": "https://avatars0.githubusercontent.com/u/1595733?v=4", + "profile": "http://vk.com/yuri.orlov", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index b3c8f964d..a9889ab9e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-100-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-101-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -218,6 +218,9 @@ This project is licensed under the terms of the MIT license.
Robert Kasperczyk

💻
Tapio Rautonen

💻 + +
Yuri Orlov

💻 + From 4db3a1cfb2dde15e545ee3ba2d5f6b06b6b46a32 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:06:01 +0300 Subject: [PATCH 139/285] docs: add varunu28 as a contributor (#1447) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0fb6f83cc..17039ce00 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -920,6 +920,15 @@ "contributions": [ "code" ] + }, + { + "login": "varunu28", + "name": "Varun Upadhyay", + "avatar_url": "https://avatars0.githubusercontent.com/u/7676016?v=4", + "profile": "https://www.linkedin.com/in/varunu28/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index a9889ab9e..0a9b45188 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-101-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-102-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -220,6 +220,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻 +
Varun Upadhyay

💻 From 047285aed7742a7d93f8b7df33cc4ab170246122 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:07:30 +0300 Subject: [PATCH 140/285] docs: add PalAditya as a contributor (#1448) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 17039ce00..3ec5459fb 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -929,6 +929,15 @@ "contributions": [ "code" ] + }, + { + "login": "PalAditya", + "name": "Aditya Pal", + "avatar_url": "https://avatars2.githubusercontent.com/u/25523604?v=4", + "profile": "https://github.com/PalAditya", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 0a9b45188..0801c677c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-102-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-103-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -221,6 +221,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻
Varun Upadhyay

💻 +
Aditya Pal

💻 From 51ef7176b191685edd39a71118dd3e5a6550e269 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:08:47 +0300 Subject: [PATCH 141/285] docs: add grzesiekkedzior as a contributor (#1449) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3ec5459fb..c7a0d5b48 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -938,6 +938,15 @@ "contributions": [ "code" ] + }, + { + "login": "grzesiekkedzior", + "name": "grzesiekkedzior", + "avatar_url": "https://avatars3.githubusercontent.com/u/23739158?v=4", + "profile": "https://github.com/grzesiekkedzior", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 0801c677c..733bb5afb 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-103-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-104-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -222,6 +222,7 @@ This project is licensed under the terms of the MIT license.
Yuri Orlov

💻
Varun Upadhyay

💻
Aditya Pal

💻 +
grzesiekkedzior

💻 From f878bf63aa17e8d618865c9c3bba2bcbeb3ebf17 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:11:51 +0300 Subject: [PATCH 142/285] docs: add sivasubramanim as a contributor (#1450) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c7a0d5b48..3a791df55 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -947,6 +947,15 @@ "contributions": [ "code" ] + }, + { + "login": "sivasubramanim", + "name": "Sivasubramani M", + "avatar_url": "https://avatars2.githubusercontent.com/u/51107434?v=4", + "profile": "https://github.com/sivasubramanim", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 733bb5afb..5ecb3a77e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-104-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-105-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -224,6 +224,9 @@ This project is licensed under the terms of the MIT license.
Aditya Pal

💻
grzesiekkedzior

💻 + +
Sivasubramani M

💻 + From f49f9a15b6a2a470a16ad9446f459f12ec8b32d8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:13:24 +0300 Subject: [PATCH 143/285] docs: add d4gg4d as a contributor (#1451) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 3a791df55..b49ea6397 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -956,6 +956,15 @@ "contributions": [ "code" ] + }, + { + "login": "d4gg4d", + "name": "Sami Airaksinen", + "avatar_url": "https://avatars2.githubusercontent.com/u/99457?v=4", + "profile": "https://github.com/d4gg4d", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 5ecb3a77e..c4d62eae4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-105-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-106-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -226,6 +226,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻 +
Sami Airaksinen

💻 From c9e30390d36209c58028674d87052a3cc66ba19f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:14:42 +0300 Subject: [PATCH 144/285] docs: add vertti as a contributor (#1452) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b49ea6397..edc3b8767 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -965,6 +965,15 @@ "contributions": [ "code" ] + }, + { + "login": "vertti", + "name": "Janne Sinivirta", + "avatar_url": "https://avatars0.githubusercontent.com/u/557751?v=4", + "profile": "https://github.com/vertti", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index c4d62eae4..e7902e395 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-106-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-107-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -227,6 +227,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻
Sami Airaksinen

💻 +
Janne Sinivirta

💻 From f2ac53edcad689ee382c701bd24eb4f736a7c0a2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:16:54 +0300 Subject: [PATCH 145/285] docs: add Bobo1239 as a contributor (#1453) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index edc3b8767..b62e7856c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -974,6 +974,15 @@ "contributions": [ "code" ] + }, + { + "login": "Bobo1239", + "name": "Boris-Chengbiao Zhou", + "avatar_url": "https://avatars1.githubusercontent.com/u/2302947?v=4", + "profile": "https://github.com/Bobo1239", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index e7902e395..65f05e5ba 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-107-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-108-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -228,6 +228,7 @@ This project is licensed under the terms of the MIT license.
Sivasubramani M

💻
Sami Airaksinen

💻
Janne Sinivirta

💻 +
Boris-Chengbiao Zhou

🖋 From de79019ece03d380534f6d21f4230eca81bf4535 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:18:15 +0300 Subject: [PATCH 146/285] docs: add Jahhein as a contributor (#1454) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index b62e7856c..7ae53172f 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -983,6 +983,15 @@ "contributions": [ "content" ] + }, + { + "login": "Jahhein", + "name": "Jacob Hein", + "avatar_url": "https://avatars2.githubusercontent.com/u/10779515?v=4", + "profile": "https://jahhein.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 65f05e5ba..adbc505a3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-108-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-109-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -230,6 +230,9 @@ This project is licensed under the terms of the MIT license.
Janne Sinivirta

💻
Boris-Chengbiao Zhou

🖋 + +
Jacob Hein

🖋 + From ec7a2025f088e9c08629f7c2bf8b1d2815310946 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:19:47 +0300 Subject: [PATCH 147/285] docs: add iamrichardjones as a contributor (#1455) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7ae53172f..46558d4fa 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -992,6 +992,15 @@ "contributions": [ "content" ] + }, + { + "login": "iamrichardjones", + "name": "Richard Jones", + "avatar_url": "https://avatars3.githubusercontent.com/u/14842151?v=4", + "profile": "https://github.com/iamrichardjones", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index adbc505a3..6b601290a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-109-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-110-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -232,6 +232,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋 +
Richard Jones

🖋 From 1e38edec151b59c6aa3c1c3907bf967ba1b3359f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:21:07 +0300 Subject: [PATCH 148/285] docs: add rachelcarmena as a contributor (#1456) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 46558d4fa..e203d5615 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1001,6 +1001,15 @@ "contributions": [ "content" ] + }, + { + "login": "rachelcarmena", + "name": "Rachel M. Carmena", + "avatar_url": "https://avatars0.githubusercontent.com/u/22792183?v=4", + "profile": "https://rachelcarmena.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 6b601290a..4b128803a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-110-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-111-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -233,6 +233,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋
Richard Jones

🖋 +
Rachel M. Carmena

🖋 From 6a28d09a3c3fe781d1a1f92743c2a46636230309 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:22:29 +0300 Subject: [PATCH 149/285] docs: add zd-zero as a contributor (#1457) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index e203d5615..038baf8ec 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1010,6 +1010,15 @@ "contributions": [ "content" ] + }, + { + "login": "zd-zero", + "name": "Zaerald Denze Lungos", + "avatar_url": "https://avatars0.githubusercontent.com/u/21978370?v=4", + "profile": "https://zd-zero.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 4b128803a..a5b0e8a73 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-111-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-112-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -234,6 +234,7 @@ This project is licensed under the terms of the MIT license.
Jacob Hein

🖋
Richard Jones

🖋
Rachel M. Carmena

🖋 +
Zaerald Denze Lungos

🖋 From 402b753480b517257d26f96de76e445922f4d8e5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:24:01 +0300 Subject: [PATCH 150/285] docs: add webpro as a contributor (#1458) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 038baf8ec..c9e63d0b3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1019,6 +1019,15 @@ "contributions": [ "content" ] + }, + { + "login": "webpro", + "name": "Lars Kappert", + "avatar_url": "https://avatars1.githubusercontent.com/u/456426?v=4", + "profile": "https://webpro.nl", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index a5b0e8a73..731f334f7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-112-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-113-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -236,6 +236,9 @@ This project is licensed under the terms of the MIT license.
Rachel M. Carmena

🖋
Zaerald Denze Lungos

🖋 + +
Lars Kappert

🖋 + From f95aadc8f54068c87430d7077903126c2b8a4e65 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 20:42:45 +0300 Subject: [PATCH 151/285] docs: add hbothra15 as a contributor (#1459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] * fix merge Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Ilkka Seppälä --- .all-contributorsrc | 3 ++- README.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index c9e63d0b3..da6e03b58 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -747,7 +747,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/7418012?v=4", "profile": "https://github.com/hbothra15", "contributions": [ - "code" + "code", + "design" ] }, { diff --git a/README.md b/README.md index 731f334f7..96ad7b25c 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Pramod Gupta

👀 +
Hemant Bothra

💻 🎨
Amarnath Chandana

💻 @@ -237,6 +237,7 @@ This project is licensed under the terms of the MIT license.
Zaerald Denze Lungos

🖋 +
Pramod Gupta

👀
Lars Kappert

🖋 From 5381387026365f3800859a4c64118b99e3dcd328 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 21:03:29 +0300 Subject: [PATCH 152/285] docs: add xiaod-dev as a contributor (#1460) * docs: update README.md [skip ci] * docs: update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index da6e03b58..9a536d34d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1029,6 +1029,15 @@ "contributions": [ "content" ] + }, + { + "login": "xiaod-dev", + "name": "Mike Liu", + "avatar_url": "https://avatars2.githubusercontent.com/u/21277644?v=4", + "profile": "https://xiaod.info", + "contributions": [ + "translation" + ] } ], "contributorsPerLine": 4, diff --git a/README.md b/README.md index 96ad7b25c..d3c815cb3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-113-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-114-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -114,7 +114,7 @@ This project is licensed under the terms of the MIT license.
GVSharma

💻
Srđan Paunović

💻
Petros G. Sideris

💻 -
Hemant Bothra

💻 🎨 +
Pramod Gupta

👀
Amarnath Chandana

💻 @@ -190,7 +190,7 @@ This project is licensed under the terms of the MIT license.
George Mavroeidis

💻 -
Hemant Bothra

💻 +
Hemant Bothra

💻 🎨
Kevin Peters

💻
George Aristy

💻 @@ -237,8 +237,8 @@ This project is licensed under the terms of the MIT license.
Zaerald Denze Lungos

🖋 -
Pramod Gupta

👀
Lars Kappert

🖋 +
Mike Liu

🌍 From 417f21ed3dda41d65e7d748c5aff8a168840b788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 20:28:47 +0300 Subject: [PATCH 153/285] Code cleanup (#1461) * Code cleanup * Fix flux tests * Fix checkstyle errors * Fix compile error --- .../AbstractDocumentTest.java | 2 +- .../abstractfactory/AbstractFactoryTest.java | 2 +- .../ConfigureForDosVisitorTest.java | 2 +- adapter/README.md | 4 +- .../iluwatar/adapter/FishingBoatAdapter.java | 2 +- .../ambassador/RemoteServiceTest.java | 2 +- .../invocation/ThreadAsyncExecutor.java | 2 +- .../iluwatar/business/delegate/Client.java | 2 +- .../business/delegate/ServiceType.java | 2 +- .../com/iluwatar/bytecode/VirtualMachine.java | 4 +- .../iluwatar/bytecode/VirtualMachineTest.java | 2 +- .../com/iluwatar/caching/CachingPolicy.java | 2 +- chain/README.md | 2 +- .../com/iluwatar/chain/RequestHandler.java | 2 +- .../com/iluwatar/collectionpipeline/Car.java | 5 +- .../iluwatar/collectionpipeline/Person.java | 2 +- .../iluwatar/collectionpipeline/AppTest.java | 2 +- command/README.md | 4 +- .../main/java/com/iluwatar/command/Size.java | 86 ++++---- .../java/com/iluwatar/command/Visibility.java | 86 ++++---- .../java/com/iluwatar/command/Wizard.java | 4 +- .../employeehandle/EmployeeDatabase.java | 2 +- .../messagingservice/MessagingDatabase.java | 2 +- .../paymentservice/PaymentDatabase.java | 2 +- .../commander/queue/QueueDatabase.java | 2 +- .../shippingservice/ShippingDatabase.java | 2 +- composite/README.md | 4 +- .../java/com/iluwatar/composite/Letter.java | 2 +- .../iluwatar/composite/LetterComposite.java | 116 +++++------ .../java/com/iluwatar/converter/User.java | 8 +- .../java/com/iluwatar/converter/UserDto.java | 8 +- .../com/iluwatar/converter/ConverterTest.java | 2 +- .../cqrs/commandes/CommandServiceImpl.java | 2 +- .../cqrs/queries/QueryServiceImpl.java | 2 +- dao/README.md | 2 +- dao/src/main/java/com/iluwatar/dao/App.java | 2 +- .../com/iluwatar/dao/InMemoryCustomerDao.java | 2 +- .../com/iluwatar/dao/DbCustomerDaoTest.java | 2 +- .../members/MessageCollectorMember.java | 2 +- .../java/com/iluwatar/datamapper/App.java | 166 ++++++++-------- .../datamapper/StudentDataMapperImpl.java | 2 +- data-transfer-object/README.md | 2 +- .../datatransfer/CustomerResource.java | 2 +- decorator/README.md | 2 +- .../com/iluwatar/decorator/ClubbedTroll.java | 2 +- .../iluwatar/decorator/SimpleTrollTest.java | 2 +- .../delegation/simple/DelegateTest.java | 2 +- dependency-injection/README.md | 2 +- .../dependency/injection/AdvancedWizard.java | 2 +- .../dependency/injection/GuiceWizard.java | 2 +- .../dependency/injection/SimpleWizard.java | 2 +- .../injection/utils/InMemoryAppender.java | 2 +- .../java/com/iluwatar/dirtyflag/World.java | 2 +- .../iluwatar/doublebuffer/FrameBuffer.java | 2 +- .../java/com/iluwatar/doublebuffer/Pixel.java | 2 +- .../java/com/iluwatar/doublebuffer/Scene.java | 2 +- .../doublechecked/locking/InventoryTest.java | 2 +- .../iluwatar/doubledispatch/Rectangle.java | 8 +- .../com/iluwatar/event/aggregator/Event.java | 2 +- .../event/aggregator/EventEmitter.java | 2 +- .../iluwatar/event/aggregator/Weekday.java | 2 +- .../event/aggregator/KingJoffreyTest.java | 2 +- .../iluwatar/event/asynchronous/Event.java | 6 +- .../event/asynchronous/EventManager.java | 4 +- .../iluwatar/eda/event/UserCreatedEvent.java | 2 +- .../iluwatar/eda/event/UserUpdatedEvent.java | 2 +- .../eda/framework/EventDispatcher.java | 2 +- .../java/com/iluwatar/eda/model/User.java | 2 +- .../java/com/iluwatar/event/queue/Audio.java | 2 +- .../java/concreteextensions/Commander.java | 2 +- .../java/concreteextensions/Sergeant.java | 2 +- .../main/java/concreteextensions/Soldier.java | 2 +- facade/README.md | 2 +- .../facade/DwarvenGoldmineFacadeTest.java | 2 +- .../factory/method/ElfBlacksmith.java | 2 +- .../iluwatar/factory/method/ElfWeapon.java | 2 +- .../factory/method/OrcBlacksmith.java | 2 +- .../iluwatar/factory/method/OrcWeapon.java | 2 +- .../iluwatar/factory/method/WeaponType.java | 2 +- .../PropertiesFeatureToggleVersion.java | 2 +- .../com/iluwatar/featuretoggle/user/User.java | 2 +- .../featuretoggle/user/UserGroup.java | 4 +- .../com/iluwatar/fluentinterface/app/App.java | 2 +- .../lazy/LazyFluentIterable.java | 2 +- .../java/com/iluwatar/flux/action/Action.java | 2 +- .../com/iluwatar/flux/action/ActionType.java | 2 +- .../com/iluwatar/flux/action/Content.java | 2 +- .../iluwatar/flux/action/ContentAction.java | 2 +- .../com/iluwatar/flux/action/MenuAction.java | 2 +- .../com/iluwatar/flux/action/MenuItem.java | 2 +- .../iluwatar/flux/dispatcher/Dispatcher.java | 2 +- .../java/com/iluwatar/flux/store/Store.java | 2 +- .../com/iluwatar/flyweight/AlchemistShop.java | 4 +- .../controller/utils/InMemoryAppender.java | 2 +- .../com/iluwatar/halfsynchalfasync/App.java | 2 +- .../AsynchronousService.java | 2 +- .../hexagonal/banking/InMemoryBank.java | 2 +- .../database/InMemoryTicketRepository.java | 2 +- .../hexagonal/domain/LotteryNumbers.java | 2 +- .../hexagonal/domain/LotteryTicketId.java | 2 +- .../hexagonal/eventlog/MongoEventLog.java | 2 +- .../hexagonal/domain/LotteryTest.java | 2 +- .../iluwatar/intercepting/filter/Client.java | 10 +- .../intercepting/filter/FilterManager.java | 2 +- .../iluwatar/intercepting/filter/Target.java | 6 +- .../iluwatar/interpreter/MinusExpression.java | 4 +- .../interpreter/MultiplyExpression.java | 4 +- .../interpreter/NumberExpression.java | 2 +- .../iluwatar/interpreter/PlusExpression.java | 4 +- iterator/README.md | 4 +- .../iluwatar/iterator/bst/BstIterator.java | 2 +- .../com/iluwatar/iterator/bst/TreeNode.java | 2 +- .../java/com/iluwatar/iterator/list/Item.java | 2 +- .../iluwatar/iterator/list/TreasureChest.java | 2 +- .../list/TreasureChestItemIterator.java | 4 +- layers/README.md | 2 +- .../java/com/iluwatar/layers/app/App.java | 2 +- .../layers/service/CakeBakingServiceImpl.java | 2 +- .../iluwatar/layers/view/CakeViewImpl.java | 2 +- .../layers/view/CakeViewImplTest.java | 2 +- .../iluwatar/lazy/loading/Java8Holder.java | 2 +- .../com.iluwatar.leaderfollowers/TaskSet.java | 2 +- .../WorkCenter.java | 2 +- .../system/systemmaster/Master.java | 2 +- .../java/com/iluwatar/mediator/Action.java | 104 +++++----- .../iluwatar/mediator/PartyMemberTest.java | 2 +- memento/README.md | 2 +- .../java/com/iluwatar/memento/StarType.java | 2 +- .../model/view/controller/Fatigue.java | 2 +- .../view/controller/GiantController.java | 4 +- .../model/view/controller/Health.java | 2 +- .../model/view/controller/Nourishment.java | 2 +- .../model/view/controller/GiantViewTest.java | 2 +- .../view/presenter/FileSelectorJFrame.java | 14 +- .../view/presenter/FileSelectorPresenter.java | 2 +- .../main/java/com/iluwatar/monad/User.java | 132 ++++++------- multiton/README.md | 6 +- .../java/com/iluwatar/multiton/Nazgul.java | 4 +- .../com/iluwatar/multiton/NazgulEnum.java | 2 +- .../com/iluwatar/multiton/NazgulName.java | 2 +- null-object/README.md | 2 +- .../com/iluwatar/nullobject/NullNode.java | 2 +- .../com/iluwatar/nullobject/TreeTest.java | 2 +- .../java/com/iluwatar/objectmother/Queen.java | 5 +- object-pool/README.md | 6 +- .../com/iluwatar/object/pool/ObjectPool.java | 4 +- .../com/iluwatar/object/pool/Oliphaunt.java | 2 +- observer/README.md | 2 +- .../java/com/iluwatar/observer/Weather.java | 2 +- .../observer/utils/InMemoryAppender.java | 2 +- .../pageobject/AlbumListPageTest.java | 2 +- .../iluwatar/pageobject/AlbumPageTest.java | 2 +- .../iluwatar/pageobject/LoginPageTest.java | 2 +- .../pageobject/AlbumListPageTest.java | 2 +- .../iluwatar/pageobject/AlbumPageTest.java | 2 +- .../iluwatar/pageobject/LoginPageTest.java | 2 +- .../partialresponse/VideoResource.java | 4 +- poison-pill/README.md | 2 +- .../iluwatar/poison/pill/SimpleMessage.java | 2 +- .../iluwatar/poison/pill/ConsumerTest.java | 2 +- .../privateclassdata/ImmutableStew.java | 100 +++++----- .../iluwatar/privateclassdata/StewData.java | 122 ++++++------ .../utils/InMemoryAppender.java | 2 +- .../com/iluwatar/producer/consumer/Item.java | 4 +- .../iluwatar/producer/consumer/ItemQueue.java | 2 +- .../java/com/iluwatar/prototype/ElfBeast.java | 2 +- .../java/com/iluwatar/prototype/ElfMage.java | 2 +- .../com/iluwatar/prototype/ElfWarlord.java | 2 +- .../iluwatar/prototype/HeroFactoryImpl.java | 130 ++++++------ .../java/com/iluwatar/prototype/OrcBeast.java | 2 +- .../java/com/iluwatar/prototype/OrcMage.java | 2 +- .../com/iluwatar/prototype/OrcWarlord.java | 2 +- .../proxy/utils/InMemoryAppender.java | 2 +- .../java/com/iluwatar/reactor/app/App.java | 4 +- .../reactor/framework/NioDatagramChannel.java | 2 +- .../reactor/framework/NioReactor.java | 4 +- .../iluwatar/reader/writer/lock/Reader.java | 6 +- .../reader/writer/lock/ReaderWriterLock.java | 4 +- .../iluwatar/reader/writer/lock/Writer.java | 6 +- .../writer/lock/utils/InMemoryAppender.java | 2 +- repository/README.md | 4 +- .../repository/PersonSpecifications.java | 4 +- .../AnnotationBasedRepositoryTest.java | 10 +- .../iluwatar/repository/RepositoryTest.java | 10 +- .../is/initialization/ClosableTest.java | 2 +- .../com/iluwatar/roleobject/CustomerCore.java | 2 +- .../java/com/iluwatar/roleobject/Role.java | 2 +- .../com/iluwatar/saga/choreography/Saga.java | 4 +- .../choreography/ServiceDiscoveryService.java | 2 +- .../saga/orchestration/ChapterResult.java | 4 +- .../com/iluwatar/saga/orchestration/Saga.java | 2 +- .../ServiceDiscoveryService.java | 2 +- .../SagaOrchestratorInternallyTest.java | 2 +- .../java/com/iluwatar/semaphore/Fruit.java | 2 +- .../com/iluwatar/semaphore/FruitBowl.java | 2 +- .../com/iluwatar/semaphore/FruitShop.java | 6 +- .../main/java/com/iluwatar/servant/App.java | 4 +- .../baas/api/AbstractDynamoDbHandler.java | 2 +- .../baas/api/SavePersonApiHandlerTest.java | 2 +- service-layer/README.md | 6 +- .../servicelayer/magic/MagicServiceImpl.java | 6 +- .../servicelocator/ServiceLocator.java | 2 +- .../iluwatar/sharding/LookupShardManager.java | 2 +- .../java/com/iluwatar/sharding/Shard.java | 2 +- singleton/README.md | 2 +- specification/README.md | 2 +- .../creature/AbstractCreature.java | 10 +- .../specification/property/Color.java | 2 +- .../iluwatar/specification/property/Mass.java | 4 +- .../specification/property/Movement.java | 2 +- .../iluwatar/specification/property/Size.java | 2 +- .../selector/ConjunctionSelector.java | 2 +- .../selector/DisjunctionSelector.java | 2 +- .../selector/NegationSelector.java | 2 +- state/README.md | 4 +- .../java/com/iluwatar/state/AngryState.java | 104 +++++----- .../com/iluwatar/state/PeacefulState.java | 104 +++++----- .../java/com/iluwatar/state/MammothTest.java | 2 +- .../stepbuilder/CharacterStepBuilder.java | 2 +- .../strategy/DragonSlayingStrategyTest.java | 2 +- .../templatemethod/StealingMethodTest.java | 2 +- throttling/README.md | 6 +- .../com/iluwatar/throttling/CallsCount.java | 2 +- .../java/com/iluwatar/throttling/Tenant.java | 4 +- .../iluwatar/throttling/B2BServiceTest.java | 2 +- .../com/iluwatar/tls/DateFormatCallable.java | 186 +++++++++--------- .../main/java/com/iluwatar/tls/Result.java | 130 ++++++------ .../iluwatar/tls/DateFormatCallableTest.java | 6 +- ...FormatCallableTestIncorrectDateFormat.java | 6 +- .../DateFormatCallableTestMultiThread.java | 10 +- tolerant-reader/README.md | 8 +- .../iluwatar/tolerantreader/RainbowFish.java | 8 +- .../java/com/iluwatar/twin/BallItemTest.java | 2 +- .../java/com/iluwatar/typeobject/App.java | 2 +- .../java/com/iluwatar/typeobject/Candy.java | 2 +- .../com/iluwatar/typeobject/CellPool.java | 2 +- unit-of-work/README.md | 4 +- .../unitofwork/StudentRepository.java | 4 +- .../java/com/iluwatar/updatemethod/World.java | 3 +- .../com/iluwatar/value/object/HeroStat.java | 5 +- visitor/README.md | 2 +- .../main/java/com/iluwatar/visitor/Unit.java | 90 ++++----- .../com/iluwatar/visitor/VisitorTest.java | 2 +- 243 files changed, 1154 insertions(+), 1162 deletions(-) diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java index d7fe5688d..c0791c30b 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java @@ -47,7 +47,7 @@ public class AbstractDocumentTest { } } - private DocumentImplementation document = new DocumentImplementation(new HashMap<>()); + private final DocumentImplementation document = new DocumentImplementation(new HashMap<>()); @Test public void shouldPutAndGetValue() { diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java index be83cc315..f3db525a1 100644 --- a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java +++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AbstractFactoryTest { - private App app = new App(); + private final App app = new App(); private KingdomFactory elfFactory; private KingdomFactory orcFactory; diff --git a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java index 8847a131e..79097a454 100644 --- a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java +++ b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitorTest.java @@ -37,7 +37,7 @@ import uk.org.lidalia.slf4jtest.TestLoggerFactory; */ public class ConfigureForDosVisitorTest { - private TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class); + private final TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class); @Test public void testVisitForZoom() { diff --git a/adapter/README.md b/adapter/README.md index b36558cbc..75edad180 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -56,7 +56,7 @@ And captain expects an implementation of `RowingBoat` interface to be able to mo ```java public class Captain { - private RowingBoat rowingBoat; + private final RowingBoat rowingBoat; // default constructor and setter for rowingBoat public Captain(RowingBoat rowingBoat) { this.rowingBoat = rowingBoat; @@ -75,7 +75,7 @@ public class FishingBoatAdapter implements RowingBoat { private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class); - private FishingBoat boat; + private final FishingBoat boat; public FishingBoatAdapter() { boat = new FishingBoat(); diff --git a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java index 5ccde5c53..39a9adab4 100644 --- a/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java +++ b/adapter/src/main/java/com/iluwatar/adapter/FishingBoatAdapter.java @@ -29,7 +29,7 @@ package com.iluwatar.adapter; */ public class FishingBoatAdapter implements RowingBoat { - private FishingBoat boat; + private final FishingBoat boat; public FishingBoatAdapter() { boat = new FishingBoat(); diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java index 3cfea2623..6c45acf66 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java @@ -48,7 +48,7 @@ class RemoteServiceTest { } private static class StaticRandomProvider implements RandomProvider { - private double value; + private final double value; StaticRandomProvider(double value) { this.value = value; diff --git a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java index 7bdf84171..e430e9ce4 100644 --- a/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java +++ b/async-method-invocation/src/main/java/com/iluwatar/async/method/invocation/ThreadAsyncExecutor.java @@ -100,7 +100,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor { void setValue(T value) { this.value = value; this.state = COMPLETED; - this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty())); + this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty())); synchronized (lock) { lock.notifyAll(); } diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java index dcf4ce6b2..2c13bc149 100644 --- a/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java +++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java @@ -28,7 +28,7 @@ package com.iluwatar.business.delegate; */ public class Client { - private BusinessDelegate businessDelegate; + private final BusinessDelegate businessDelegate; public Client(BusinessDelegate businessDelegate) { this.businessDelegate = businessDelegate; diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java index 87fd1562d..c0f02b5e3 100644 --- a/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java +++ b/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java @@ -28,5 +28,5 @@ package com.iluwatar.business.delegate; */ public enum ServiceType { - EJB, JMS; + EJB, JMS } diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java index 5afc2fb93..c45301c29 100644 --- a/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java +++ b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java @@ -30,9 +30,9 @@ import java.util.Stack; */ public class VirtualMachine { - private Stack stack = new Stack<>(); + private final Stack stack = new Stack<>(); - private Wizard[] wizards = new Wizard[2]; + private final Wizard[] wizards = new Wizard[2]; /** * Constructor. diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java index 61a316f5a..4518ca310 100644 --- a/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java +++ b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java @@ -104,7 +104,7 @@ public class VirtualMachineTest { bytecode[2] = LITERAL.getIntValue(); bytecode[3] = 50; // health amount bytecode[4] = SET_HEALTH.getIntValue(); - bytecode[5] = LITERAL.getIntValue();; + bytecode[5] = LITERAL.getIntValue(); bytecode[6] = wizardNumber; bytecode[7] = GET_HEALTH.getIntValue(); diff --git a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java index 6bc6dbd77..84b8307f3 100644 --- a/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java +++ b/caching/src/main/java/com/iluwatar/caching/CachingPolicy.java @@ -29,7 +29,7 @@ package com.iluwatar.caching; public enum CachingPolicy { THROUGH("through"), AROUND("around"), BEHIND("behind"), ASIDE("aside"); - private String policy; + private final String policy; CachingPolicy(String policy) { this.policy = policy; diff --git a/chain/README.md b/chain/README.md index cdc5966bd..f11f0c59e 100644 --- a/chain/README.md +++ b/chain/README.md @@ -65,7 +65,7 @@ Then the request handler hierarchy ```java public abstract class RequestHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class); - private RequestHandler next; + private final RequestHandler next; public RequestHandler(RequestHandler next) { this.next = next; diff --git a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java index 7923f03a6..4778ecf91 100644 --- a/chain/src/main/java/com/iluwatar/chain/RequestHandler.java +++ b/chain/src/main/java/com/iluwatar/chain/RequestHandler.java @@ -33,7 +33,7 @@ public abstract class RequestHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class); - private RequestHandler next; + private final RequestHandler next; public RequestHandler(RequestHandler next) { this.next = next; diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java index 2828cffd4..cffdc7c82 100644 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Car.java @@ -87,10 +87,7 @@ public class Car { } else if (!model.equals(other.model)) { return false; } - if (year != other.year) { - return false; - } - return true; + return year == other.year; } public String getMake() { diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java index 2e564b701..3e25f6993 100644 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java +++ b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/Person.java @@ -29,7 +29,7 @@ import java.util.List; * A Person class that has the list of cars that the person owns and use. */ public class Person { - private List cars; + private final List cars; /** * Constructor to create an instance of person. diff --git a/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java index 6bf373e81..cedc492b9 100644 --- a/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java +++ b/collection-pipeline/src/test/java/com/iluwatar/collectionpipeline/AppTest.java @@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory; public class AppTest { private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class); - private List cars = CarFactory.createCars(); + private final List cars = CarFactory.createCars(); @Test public void testGetModelsAfter2000UsingFor() { diff --git a/command/README.md b/command/README.md index 02a290e4d..fc0a11d9f 100644 --- a/command/README.md +++ b/command/README.md @@ -36,8 +36,8 @@ public class Wizard { private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); - private Deque undoStack = new LinkedList<>(); - private Deque redoStack = new LinkedList<>(); + private final Deque undoStack = new LinkedList<>(); + private final Deque redoStack = new LinkedList<>(); public Wizard() {} diff --git a/command/src/main/java/com/iluwatar/command/Size.java b/command/src/main/java/com/iluwatar/command/Size.java index ae327d8b1..c9aeb7017 100644 --- a/command/src/main/java/com/iluwatar/command/Size.java +++ b/command/src/main/java/com/iluwatar/command/Size.java @@ -1,43 +1,43 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.command; - -/** - * Enumeration for target size. - */ -public enum Size { - - SMALL("small"), NORMAL("normal"); - - private String title; - - Size(String title) { - this.title = title; - } - - @Override - public String toString() { - return title; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.command; + +/** + * Enumeration for target size. + */ +public enum Size { + + SMALL("small"), NORMAL("normal"); + + private final String title; + + Size(String title) { + this.title = title; + } + + @Override + public String toString() { + return title; + } +} diff --git a/command/src/main/java/com/iluwatar/command/Visibility.java b/command/src/main/java/com/iluwatar/command/Visibility.java index 3c48990a0..8fe0ce7bb 100644 --- a/command/src/main/java/com/iluwatar/command/Visibility.java +++ b/command/src/main/java/com/iluwatar/command/Visibility.java @@ -1,43 +1,43 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.command; - -/** - * Enumeration for target visibility. - */ -public enum Visibility { - - VISIBLE("visible"), INVISIBLE("invisible"); - - private String title; - - Visibility(String title) { - this.title = title; - } - - @Override - public String toString() { - return title; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.command; + +/** + * Enumeration for target visibility. + */ +public enum Visibility { + + VISIBLE("visible"), INVISIBLE("invisible"); + + private final String title; + + Visibility(String title) { + this.title = title; + } + + @Override + public String toString() { + return title; + } +} diff --git a/command/src/main/java/com/iluwatar/command/Wizard.java b/command/src/main/java/com/iluwatar/command/Wizard.java index e0b973265..dd469d3c0 100644 --- a/command/src/main/java/com/iluwatar/command/Wizard.java +++ b/command/src/main/java/com/iluwatar/command/Wizard.java @@ -35,8 +35,8 @@ public class Wizard { private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); - private Deque undoStack = new LinkedList<>(); - private Deque redoStack = new LinkedList<>(); + private final Deque undoStack = new LinkedList<>(); + private final Deque redoStack = new LinkedList<>(); public Wizard() { // comment to ignore sonar issue: LEVEL critical diff --git a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java index 496bb545a..69ebc1fd9 100644 --- a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java @@ -33,7 +33,7 @@ import java.util.Hashtable; */ public class EmployeeDatabase extends Database { - private Hashtable data; + private final Hashtable data; public EmployeeDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java index fbba52cac..22ad733cb 100644 --- a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java @@ -33,7 +33,7 @@ import java.util.Hashtable; */ public class MessagingDatabase extends Database { - private Hashtable data; + private final Hashtable data; public MessagingDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java index 644979883..bf9e846bb 100644 --- a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java @@ -34,7 +34,7 @@ import java.util.Hashtable; public class PaymentDatabase extends Database { - private Hashtable data; + private final Hashtable data; public PaymentDatabase() { this.data = new Hashtable<>(); diff --git a/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java index 91a7966f7..003a7da46 100644 --- a/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java @@ -35,7 +35,7 @@ import java.util.List; public class QueueDatabase extends Database { - private Queue data; + private final Queue data; public List exceptionsList; public QueueDatabase(Exception... exc) { diff --git a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java index 305122db2..abaf27c9d 100644 --- a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java +++ b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java @@ -34,7 +34,7 @@ import java.util.Hashtable; public class ShippingDatabase extends Database { - private Hashtable data; + private final Hashtable data; public ShippingDatabase() { this.data = new Hashtable<>(); diff --git a/composite/README.md b/composite/README.md index 25b553b76..dad6fb5a5 100644 --- a/composite/README.md +++ b/composite/README.md @@ -34,7 +34,7 @@ Taking our sentence example from above. Here we have the base class and differen ```java public abstract class LetterComposite { - private List children = new ArrayList<>(); + private final List children = new ArrayList<>(); public void add(LetterComposite letter) { children.add(letter); @@ -59,7 +59,7 @@ public abstract class LetterComposite { public class Letter extends LetterComposite { - private char character; + private final char character; public Letter(char c) { this.character = c; diff --git a/composite/src/main/java/com/iluwatar/composite/Letter.java b/composite/src/main/java/com/iluwatar/composite/Letter.java index ab2d496ea..00b1a9639 100644 --- a/composite/src/main/java/com/iluwatar/composite/Letter.java +++ b/composite/src/main/java/com/iluwatar/composite/Letter.java @@ -28,7 +28,7 @@ package com.iluwatar.composite; */ public class Letter extends LetterComposite { - private char character; + private final char character; public Letter(char c) { this.character = c; diff --git a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java index 25808c468..0daf88222 100644 --- a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java +++ b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java @@ -1,58 +1,58 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.composite; - -import java.util.ArrayList; -import java.util.List; - -/** - * Composite interface. - */ -public abstract class LetterComposite { - - private List children = new ArrayList<>(); - - public void add(LetterComposite letter) { - children.add(letter); - } - - public int count() { - return children.size(); - } - - protected void printThisBefore() { - } - - protected void printThisAfter() { - } - - /** - * Print. - */ - public void print() { - printThisBefore(); - children.forEach(LetterComposite::print); - printThisAfter(); - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.composite; + +import java.util.ArrayList; +import java.util.List; + +/** + * Composite interface. + */ +public abstract class LetterComposite { + + private final List children = new ArrayList<>(); + + public void add(LetterComposite letter) { + children.add(letter); + } + + public int count() { + return children.size(); + } + + protected void printThisBefore() { + } + + protected void printThisAfter() { + } + + /** + * Print. + */ + public void print() { + printThisBefore(); + children.forEach(LetterComposite::print); + printThisAfter(); + } +} diff --git a/converter/src/main/java/com/iluwatar/converter/User.java b/converter/src/main/java/com/iluwatar/converter/User.java index 637d77a25..2c1ba9ff0 100644 --- a/converter/src/main/java/com/iluwatar/converter/User.java +++ b/converter/src/main/java/com/iluwatar/converter/User.java @@ -29,10 +29,10 @@ import java.util.Objects; * User class. */ public class User { - private String firstName; - private String lastName; - private boolean isActive; - private String userId; + private final String firstName; + private final String lastName; + private final boolean isActive; + private final String userId; /** * Constructor. diff --git a/converter/src/main/java/com/iluwatar/converter/UserDto.java b/converter/src/main/java/com/iluwatar/converter/UserDto.java index e75aaab8c..67a886087 100644 --- a/converter/src/main/java/com/iluwatar/converter/UserDto.java +++ b/converter/src/main/java/com/iluwatar/converter/UserDto.java @@ -30,10 +30,10 @@ import java.util.Objects; */ public class UserDto { - private String firstName; - private String lastName; - private boolean isActive; - private String email; + private final String firstName; + private final String lastName; + private final boolean isActive; + private final String email; /** * Constructor. diff --git a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java index d9e4e418b..46aca82a7 100644 --- a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java +++ b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class ConverterTest { - private UserConverter userConverter = new UserConverter(); + private final UserConverter userConverter = new UserConverter(); /** * Tests whether a converter created of opposite functions holds equality as a bijection. diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java index ba08811e7..e402adad8 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java @@ -34,7 +34,7 @@ import org.hibernate.SessionFactory; */ public class CommandServiceImpl implements ICommandService { - private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); private Author getAuthorByUsername(String username) { Author author; diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java index 9b008402e..d30c0f386 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java @@ -38,7 +38,7 @@ import org.hibernate.transform.Transformers; */ public class QueryServiceImpl implements IQueryService { - private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); @Override public Author getAuthorByUsername(String username) { diff --git a/dao/README.md b/dao/README.md index 4b65679c4..11e5f9ca3 100644 --- a/dao/README.md +++ b/dao/README.md @@ -112,7 +112,7 @@ public interface CustomerDao { public class InMemoryCustomerDao implements CustomerDao { - private Map idToCustomer = new HashMap<>(); + private final Map idToCustomer = new HashMap<>(); @Override public Stream getAll() { diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java index de9c7b7c1..6d578bc79 100644 --- a/dao/src/main/java/com/iluwatar/dao/App.java +++ b/dao/src/main/java/com/iluwatar/dao/App.java @@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory; */ public class App { private static final String DB_URL = "jdbc:h2:~/dao"; - private static Logger log = LoggerFactory.getLogger(App.class); + private static final Logger log = LoggerFactory.getLogger(App.class); private static final String ALL_CUSTOMERS = "customerDao.getAllCustomers(): "; /** diff --git a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java index 6dbfa367a..0a3bd40e3 100644 --- a/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java +++ b/dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java @@ -36,7 +36,7 @@ import java.util.stream.Stream; */ public class InMemoryCustomerDao implements CustomerDao { - private Map idToCustomer = new HashMap<>(); + private final Map idToCustomer = new HashMap<>(); /** * An eagerly evaluated stream of customers stored in memory. diff --git a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java index b7a0b9769..8155cda79 100644 --- a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java +++ b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java @@ -50,7 +50,7 @@ public class DbCustomerDaoTest { private static final String DB_URL = "jdbc:h2:~/dao"; private DbCustomerDao dao; - private Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); + private final Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); /** * Creates customers schema. diff --git a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java index 5a8218225..d77d56b9f 100644 --- a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java +++ b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java @@ -41,7 +41,7 @@ public class MessageCollectorMember implements Member { private final String name; - private List messages = new ArrayList<>(); + private final List messages = new ArrayList<>(); public MessageCollectorMember(String name) { this.name = name; diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java index 9bfc32952..09c027401 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java @@ -1,83 +1,83 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.datamapper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the - * database. Its responsibility is to transfer data between the two and also to isolate them from - * each other. With Data Mapper the in-memory objects needn't know even that there's a database - * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The - * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper , - * Data Mapper itself is even unknown to the domain layer. - * - *

The below example demonstrates basic CRUD operations: Create, Read, Update, and Delete. - */ -public final class App { - - private static Logger log = LoggerFactory.getLogger(App.class); - private static final String STUDENT_STRING = "App.main(), student : "; - - - /** - * Program entry point. - * - * @param args command line args. - */ - public static void main(final String... args) { - - /* Create new data mapper for type 'first' */ - final var mapper = new StudentDataMapperImpl(); - - /* Create new student */ - var student = new Student(1, "Adam", 'A'); - - /* Add student in respectibe store */ - mapper.insert(student); - - log.debug(STUDENT_STRING + student + ", is inserted"); - - /* Find this student */ - final var studentToBeFound = mapper.find(student.getStudentId()); - - log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); - - /* Update existing student object */ - student = new Student(student.getStudentId(), "AdamUpdated", 'A'); - - /* Update student in respectibe db */ - mapper.update(student); - - log.debug(STUDENT_STRING + student + ", is updated"); - log.debug(STUDENT_STRING + student + ", is going to be deleted"); - - /* Delete student in db */ - mapper.delete(student); - } - - private App() { - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.datamapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the + * database. Its responsibility is to transfer data between the two and also to isolate them from + * each other. With Data Mapper the in-memory objects needn't know even that there's a database + * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The + * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper , + * Data Mapper itself is even unknown to the domain layer. + * + *

The below example demonstrates basic CRUD operations: Create, Read, Update, and Delete. + */ +public final class App { + + private static final Logger log = LoggerFactory.getLogger(App.class); + private static final String STUDENT_STRING = "App.main(), student : "; + + + /** + * Program entry point. + * + * @param args command line args. + */ + public static void main(final String... args) { + + /* Create new data mapper for type 'first' */ + final var mapper = new StudentDataMapperImpl(); + + /* Create new student */ + var student = new Student(1, "Adam", 'A'); + + /* Add student in respectibe store */ + mapper.insert(student); + + log.debug(STUDENT_STRING + student + ", is inserted"); + + /* Find this student */ + final var studentToBeFound = mapper.find(student.getStudentId()); + + log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); + + /* Update existing student object */ + student = new Student(student.getStudentId(), "AdamUpdated", 'A'); + + /* Update student in respectibe db */ + mapper.update(student); + + log.debug(STUDENT_STRING + student + ", is updated"); + log.debug(STUDENT_STRING + student + ", is going to be deleted"); + + /* Delete student in db */ + mapper.delete(student); + } + + private App() { + } +} diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java index 85ad4aa8d..7abe04e3f 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java @@ -33,7 +33,7 @@ import java.util.Optional; public final class StudentDataMapperImpl implements StudentDataMapper { /* Note: Normally this would be in the form of an actual database */ - private List students = new ArrayList<>(); + private final List students = new ArrayList<>(); @Override public Optional find(int studentId) { diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index e9286ce03..fd0ff1137 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -64,7 +64,7 @@ Customer resource class acts as the server for customer information. ```java public class CustomerResource { - private List customers; + private final List customers; public CustomerResource(List customers) { this.customers = customers; diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java index 7e4b8340d..d0a153f6f 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java @@ -30,7 +30,7 @@ import java.util.List; * has all customer details. */ public class CustomerResource { - private List customers; + private final List customers; /** * Initialise resource with existing customers. diff --git a/decorator/README.md b/decorator/README.md index a9dd5d745..26dbd1803 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -70,7 +70,7 @@ public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); - private Troll decorated; + private final Troll decorated; public ClubbedTroll(Troll decorated) { this.decorated = decorated; diff --git a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java index 70fd15489..74a1434e1 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java @@ -33,7 +33,7 @@ public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); - private Troll decorated; + private final Troll decorated; public ClubbedTroll(Troll decorated) { this.decorated = decorated; diff --git a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java index c9f62407c..a398135e6 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java @@ -68,7 +68,7 @@ public class SimpleTrollTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java index 2da1e0571..8aefc4b56 100644 --- a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java +++ b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java @@ -86,7 +86,7 @@ public class DelegateTest { */ private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/dependency-injection/README.md b/dependency-injection/README.md index abf647b50..b47c1d2f9 100644 --- a/dependency-injection/README.md +++ b/dependency-injection/README.md @@ -62,7 +62,7 @@ public interface Wizard { public class AdvancedWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; public AdvancedWizard(Tobacco tobacco) { this.tobacco = tobacco; diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java index e0c952186..f0ff2da94 100644 --- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java +++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/AdvancedWizard.java @@ -29,7 +29,7 @@ package com.iluwatar.dependency.injection; */ public class AdvancedWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; public AdvancedWizard(Tobacco tobacco) { this.tobacco = tobacco; diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java index 319a635eb..d769ffd46 100644 --- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java +++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/GuiceWizard.java @@ -31,7 +31,7 @@ import javax.inject.Inject; */ public class GuiceWizard implements Wizard { - private Tobacco tobacco; + private final Tobacco tobacco; @Inject public GuiceWizard(Tobacco tobacco) { diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java index 40bca0ffb..0136ff69f 100644 --- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java +++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/SimpleWizard.java @@ -29,7 +29,7 @@ package com.iluwatar.dependency.injection; */ public class SimpleWizard implements Wizard { - private OldTobyTobacco tobacco = new OldTobyTobacco(); + private final OldTobyTobacco tobacco = new OldTobyTobacco(); public void smoke() { tobacco.smoke(this); diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java index 9d0ad1b3b..d91099af9 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/utils/InMemoryAppender.java @@ -37,7 +37,7 @@ import java.util.List; */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java index db60924c1..1d4fbfa75 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java @@ -34,7 +34,7 @@ import java.util.List; public class World { private List countries; - private DataFetcher df; + private final DataFetcher df; public World() { this.countries = new ArrayList(); diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index 5f683cf1e..4b974a2e8 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -33,7 +33,7 @@ public class FrameBuffer implements Buffer { public static final int WIDTH = 10; public static final int HEIGHT = 8; - private Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; + private final Pixel[] pixels = new Pixel[WIDTH * HEIGHT]; public FrameBuffer() { clearAll(); diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java index 501797743..54f130b1d 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Pixel.java @@ -31,7 +31,7 @@ public enum Pixel { WHITE(0), BLACK(1); - private int color; + private final int color; Pixel(int color) { this.color = color; diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java index 2c1503918..8ee72ded4 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -35,7 +35,7 @@ public class Scene { private static final Logger LOGGER = LoggerFactory.getLogger(Scene.class); - private Buffer[] frameBuffers; + private final Buffer[] frameBuffers; private int current; diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java index e8ea7c6f8..fe0cbf5e9 100644 --- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java +++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java @@ -109,7 +109,7 @@ public class InventoryTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java index bd832287c..ea18ca3dc 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Rectangle.java @@ -28,10 +28,10 @@ package com.iluwatar.doubledispatch; */ public class Rectangle { - private int left; - private int top; - private int right; - private int bottom; + private final int left; + private final int top; + private final int right; + private final int bottom; /** * Constructor. diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java index 7a125c042..91bb020ee 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Event.java @@ -31,7 +31,7 @@ public enum Event { STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED( "Traitor detected"); - private String description; + private final String description; Event(String description) { this.description = description; diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java index 9985cee60..7d3f32a68 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/EventEmitter.java @@ -31,7 +31,7 @@ import java.util.List; */ public abstract class EventEmitter { - private List observers; + private final List observers; public EventEmitter() { observers = new LinkedList<>(); diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java index 9ec61339c..1e0ce9491 100644 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java +++ b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/Weekday.java @@ -36,7 +36,7 @@ public enum Weekday { SATURDAY("Saturday"), SUNDAY("Sunday"); - private String description; + private final String description; Weekday(String description) { this.description = description; diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java index a8bb6cbaa..f8aa5cb37 100644 --- a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java @@ -74,7 +74,7 @@ public class KingJoffreyTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java index 6925a2ffd..68c4c9781 100644 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java +++ b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/Event.java @@ -33,9 +33,9 @@ public class Event implements IEvent, Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Event.class); - private int eventId; - private int eventTime; - private boolean isSynchronous; + private final int eventId; + private final int eventTime; + private final boolean isSynchronous; private Thread thread; private boolean isComplete = false; private ThreadCompleteListener eventListener; diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java index 14d28860b..55671fd82 100644 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java +++ b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/EventManager.java @@ -43,8 +43,8 @@ public class EventManager implements ThreadCompleteListener { public static final int MAX_ID = MAX_RUNNING_EVENTS; public static final int MAX_EVENT_TIME = 1800; // in seconds / 30 minutes. private int currentlyRunningSyncEvent = -1; - private Random rand; - private Map eventPool; + private final Random rand; + private final Map eventPool; private static final String DOES_NOT_EXIST = " does not exist."; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java index c18426c95..dd5e65a9a 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserCreatedEvent.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.model.User; */ public class UserCreatedEvent extends AbstractEvent { - private User user; + private final User user; public UserCreatedEvent(User user) { this.user = user; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java index 59583053c..05370c6a6 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/event/UserUpdatedEvent.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.model.User; */ public class UserUpdatedEvent extends AbstractEvent { - private User user; + private final User user; public UserUpdatedEvent(User user) { this.user = user; diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java index dd72c1e93..74a7ee145 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/framework/EventDispatcher.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class EventDispatcher { - private Map, Handler> handlers; + private final Map, Handler> handlers; public EventDispatcher() { handlers = new HashMap<>(); diff --git a/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java index 1492c175c..0c9f12501 100644 --- a/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java +++ b/event-driven-architecture/src/main/java/com/iluwatar/eda/model/User.java @@ -32,7 +32,7 @@ import com.iluwatar.eda.event.UserUpdatedEvent; */ public class User { - private String username; + private final String username; public User(String username) { this.username = username; diff --git a/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java index 4286a5ed0..a0ff5d987 100644 --- a/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java +++ b/event-queue/src/main/java/com/iluwatar/event/queue/Audio.java @@ -49,7 +49,7 @@ public class Audio { private volatile Thread updateThread = null; - private PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING]; + private final PlayMessage[] pendingAudio = new PlayMessage[MAX_PENDING]; // Visible only for testing purposes Audio() { diff --git a/extension-objects/src/main/java/concreteextensions/Commander.java b/extension-objects/src/main/java/concreteextensions/Commander.java index 5a0552b20..1d8054562 100644 --- a/extension-objects/src/main/java/concreteextensions/Commander.java +++ b/extension-objects/src/main/java/concreteextensions/Commander.java @@ -35,7 +35,7 @@ public class Commander implements CommanderExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Commander.class); - private CommanderUnit unit; + private final CommanderUnit unit; public Commander(CommanderUnit commanderUnit) { this.unit = commanderUnit; diff --git a/extension-objects/src/main/java/concreteextensions/Sergeant.java b/extension-objects/src/main/java/concreteextensions/Sergeant.java index a45b82f11..4f5a474b3 100644 --- a/extension-objects/src/main/java/concreteextensions/Sergeant.java +++ b/extension-objects/src/main/java/concreteextensions/Sergeant.java @@ -35,7 +35,7 @@ public class Sergeant implements SergeantExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Sergeant.class); - private SergeantUnit unit; + private final SergeantUnit unit; public Sergeant(SergeantUnit sergeantUnit) { this.unit = sergeantUnit; diff --git a/extension-objects/src/main/java/concreteextensions/Soldier.java b/extension-objects/src/main/java/concreteextensions/Soldier.java index b47ba595d..d500ab604 100644 --- a/extension-objects/src/main/java/concreteextensions/Soldier.java +++ b/extension-objects/src/main/java/concreteextensions/Soldier.java @@ -34,7 +34,7 @@ import units.SoldierUnit; public class Soldier implements SoldierExtension { private static final Logger LOGGER = LoggerFactory.getLogger(Soldier.class); - private SoldierUnit unit; + private final SoldierUnit unit; public Soldier(SoldierUnit soldierUnit) { this.unit = soldierUnit; diff --git a/facade/README.md b/facade/README.md index 018c493a7..ce9d892b6 100644 --- a/facade/README.md +++ b/facade/README.md @@ -83,7 +83,7 @@ public abstract class DwarvenMineWorker { public abstract String name(); - static enum Action { + enum Action { GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK } } diff --git a/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java b/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java index 3b67f3754..10d6e1ecd 100644 --- a/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java +++ b/facade/src/test/java/com/iluwatar/facade/DwarvenGoldmineFacadeTest.java @@ -110,7 +110,7 @@ public class DwarvenGoldmineFacadeTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java b/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java index b6f29e43a..99ebcef65 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class ElfBlacksmith implements Blacksmith { - private static Map ELFARSENAL; + private static final Map ELFARSENAL; static { ELFARSENAL = new HashMap<>(WeaponType.values().length); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java index 66a6ea7e7..208dfa277 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java @@ -28,7 +28,7 @@ package com.iluwatar.factory.method; */ public class ElfWeapon implements Weapon { - private WeaponType weaponType; + private final WeaponType weaponType; public ElfWeapon(WeaponType weaponType) { this.weaponType = weaponType; diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java b/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java index b04830085..ea99200de 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class OrcBlacksmith implements Blacksmith { - private static Map ORCARSENAL; + private static final Map ORCARSENAL; static { ORCARSENAL = new HashMap<>(WeaponType.values().length); diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java index b35adf798..af1ee5bcf 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java @@ -28,7 +28,7 @@ package com.iluwatar.factory.method; */ public class OrcWeapon implements Weapon { - private WeaponType weaponType; + private final WeaponType weaponType; public OrcWeapon(WeaponType weaponType) { this.weaponType = weaponType; diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java b/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java index 73ab10dd6..6c7c86712 100644 --- a/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java +++ b/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java @@ -30,7 +30,7 @@ public enum WeaponType { SHORT_SWORD("short sword"), SPEAR("spear"), AXE("axe"), UNDEFINED(""); - private String title; + private final String title; WeaponType(String title) { this.title = title; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java index 6e2281b9a..ed6e69518 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -42,7 +42,7 @@ import java.util.Properties; */ public class PropertiesFeatureToggleVersion implements Service { - private boolean isEnhanced; + private final boolean isEnhanced; /** * Creates an instance of {@link PropertiesFeatureToggleVersion} using the passed {@link diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index 5c660ca59..7924f86e8 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -29,7 +29,7 @@ package com.iluwatar.featuretoggle.user; */ public class User { - private String name; + private final String name; /** * Default Constructor setting the username. diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 524ea6ef8..7b644afd7 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -35,8 +35,8 @@ import java.util.List; */ public class UserGroup { - private static List freeGroup = new ArrayList<>(); - private static List paidGroup = new ArrayList<>(); + private static final List freeGroup = new ArrayList<>(); + private static final List paidGroup = new ArrayList<>(); /** diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java index 547c657e4..09513163c 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java @@ -94,7 +94,7 @@ public class App { .filter(positives()) .first(4) .last(2) - .map(number -> "String[" + valueOf(number) + "]") + .map(number -> "String[" + number + "]") .asList(); prettyPrint("The lazy list contains the last two of the first four positive numbers " + "mapped to Strings: ", lastTwoOfFirstFourStringMapped); diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java index f001c532f..966f35287 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java @@ -198,7 +198,7 @@ public class LazyFluentIterable implements FluentIterable { @Override public Iterator iterator() { return new DecoratingIterator(null) { - Iterator oldTypeIterator = iterable.iterator(); + final Iterator oldTypeIterator = iterable.iterator(); @Override public T computeNext() { diff --git a/flux/src/main/java/com/iluwatar/flux/action/Action.java b/flux/src/main/java/com/iluwatar/flux/action/Action.java index 6a5f608c2..c8e2e012b 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/Action.java +++ b/flux/src/main/java/com/iluwatar/flux/action/Action.java @@ -28,7 +28,7 @@ package com.iluwatar.flux.action; */ public abstract class Action { - private ActionType type; + private final ActionType type; public Action(ActionType type) { this.type = type; diff --git a/flux/src/main/java/com/iluwatar/flux/action/ActionType.java b/flux/src/main/java/com/iluwatar/flux/action/ActionType.java index 6399d2806..e84954efd 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/ActionType.java +++ b/flux/src/main/java/com/iluwatar/flux/action/ActionType.java @@ -28,6 +28,6 @@ package com.iluwatar.flux.action; */ public enum ActionType { - MENU_ITEM_SELECTED, CONTENT_CHANGED; + MENU_ITEM_SELECTED, CONTENT_CHANGED } diff --git a/flux/src/main/java/com/iluwatar/flux/action/Content.java b/flux/src/main/java/com/iluwatar/flux/action/Content.java index 59a63ec18..6fb2e3e0e 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/Content.java +++ b/flux/src/main/java/com/iluwatar/flux/action/Content.java @@ -31,7 +31,7 @@ public enum Content { PRODUCTS("Products - This page lists the company's products."), COMPANY( "Company - This page displays information about the company."); - private String title; + private final String title; Content(String title) { this.title = title; diff --git a/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java b/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java index 3b29b6b4e..c70561a65 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java +++ b/flux/src/main/java/com/iluwatar/flux/action/ContentAction.java @@ -28,7 +28,7 @@ package com.iluwatar.flux.action; */ public class ContentAction extends Action { - private Content content; + private final Content content; public ContentAction(Content content) { super(ActionType.CONTENT_CHANGED); diff --git a/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java b/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java index 5ddeefde4..f833a6187 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java +++ b/flux/src/main/java/com/iluwatar/flux/action/MenuAction.java @@ -29,7 +29,7 @@ package com.iluwatar.flux.action; */ public class MenuAction extends Action { - private MenuItem menuItem; + private final MenuItem menuItem; public MenuAction(MenuItem menuItem) { super(ActionType.MENU_ITEM_SELECTED); diff --git a/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java b/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java index f251e1dd7..90fac3e2e 100644 --- a/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java +++ b/flux/src/main/java/com/iluwatar/flux/action/MenuItem.java @@ -30,7 +30,7 @@ public enum MenuItem { HOME("Home"), PRODUCTS("Products"), COMPANY("Company"); - private String title; + private final String title; MenuItem(String title) { this.title = title; diff --git a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java index cf09ecf68..27d374f5d 100644 --- a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java +++ b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java @@ -39,7 +39,7 @@ public final class Dispatcher { private static Dispatcher instance = new Dispatcher(); - private List stores = new LinkedList<>(); + private final List stores = new LinkedList<>(); private Dispatcher() { } diff --git a/flux/src/main/java/com/iluwatar/flux/store/Store.java b/flux/src/main/java/com/iluwatar/flux/store/Store.java index cfbdf4af5..34188fff2 100644 --- a/flux/src/main/java/com/iluwatar/flux/store/Store.java +++ b/flux/src/main/java/com/iluwatar/flux/store/Store.java @@ -33,7 +33,7 @@ import java.util.List; */ public abstract class Store { - private List views = new LinkedList<>(); + private final List views = new LinkedList<>(); public abstract void onAction(Action action); diff --git a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java index 4fa7312e5..e7af8ee00 100644 --- a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java +++ b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java @@ -34,8 +34,8 @@ public class AlchemistShop { private static final Logger LOGGER = LoggerFactory.getLogger(AlchemistShop.class); - private List topShelf; - private List bottomShelf; + private final List topShelf; + private final List bottomShelf; /** * Constructor. diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java b/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java index 57cfb2454..8cbf7c631 100644 --- a/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java +++ b/front-controller/src/test/java/com/iluwatar/front/controller/utils/InMemoryAppender.java @@ -36,7 +36,7 @@ import java.util.List; */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java index 7df2264ab..d013924cb 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java @@ -95,7 +95,7 @@ public class App { * ArithmeticSumTask. */ static class ArithmeticSumTask implements AsyncTask { - private long numberOfElements; + private final long numberOfElements; public ArithmeticSumTask(long numberOfElements) { this.numberOfElements = numberOfElements; diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java index 3a3bb474c..32f5e9d4a 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java @@ -48,7 +48,7 @@ public class AsynchronousService { * tasks should be performed in the background which does not affect the performance of main * thread. */ - private ExecutorService service; + private final ExecutorService service; /** * Creates an asynchronous service using {@code workQueue} as communication channel between diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java index 1a0fdb6b0..746b93508 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class InMemoryBank implements WireTransfers { - private static Map accounts = new HashMap<>(); + private static final Map accounts = new HashMap<>(); static { accounts diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java index 973747acc..5c0461843 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java @@ -34,7 +34,7 @@ import java.util.Optional; */ public class InMemoryTicketRepository implements LotteryTicketRepository { - private static Map tickets = new HashMap<>(); + private static final Map tickets = new HashMap<>(); @Override public Optional findById(LotteryTicketId id) { diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java index 8988bba88..acdd2b8c5 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java @@ -116,7 +116,7 @@ public class LotteryNumbers { */ private static class RandomNumberGenerator { - private PrimitiveIterator.OfInt randomIterator; + private final PrimitiveIterator.OfInt randomIterator; /** * Initialize a new random number generator that generates random numbers in the range [min, diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java index dfa324449..114e78c9c 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class LotteryTicketId { - private static AtomicInteger numAllocated = new AtomicInteger(0); + private static final AtomicInteger numAllocated = new AtomicInteger(0); private final int id; public LotteryTicketId() { diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java index ba46f2d97..c632debe8 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java @@ -41,7 +41,7 @@ public class MongoEventLog implements LotteryEventLog { private MongoDatabase database; private MongoCollection eventsCollection; - private StdOutEventLog stdOutEventLog = new StdOutEventLog(); + private final StdOutEventLog stdOutEventLog = new StdOutEventLog(); /** * Constructor. diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java index 6d3ba8bc5..541b2b98b 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java @@ -43,7 +43,7 @@ import org.junit.jupiter.api.Test; */ class LotteryTest { - private Injector injector; + private final Injector injector; @Inject private LotteryAdministration administration; @Inject diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java index 656008c10..52aa890c1 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Client.java @@ -51,11 +51,11 @@ public class Client extends JFrame { // NOSONAR private static final long serialVersionUID = 1L; private transient FilterManager filterManager; - private JLabel jl; - private JTextField[] jtFields; - private JTextArea[] jtAreas; - private JButton clearButton; - private JButton processButton; + private final JLabel jl; + private final JTextField[] jtFields; + private final JTextArea[] jtAreas; + private final JButton clearButton; + private final JButton processButton; /** * Constructor. diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java index e8f3b941f..91e438882 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/FilterManager.java @@ -30,7 +30,7 @@ package com.iluwatar.intercepting.filter; */ public class FilterManager { - private FilterChain filterChain; + private final FilterChain filterChain; public FilterManager() { filterChain = new FilterChain(); diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java index 08ed715b1..db552356d 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/Target.java @@ -46,9 +46,9 @@ public class Target extends JFrame { //NOSONAR private static final long serialVersionUID = 1L; - private JTable jt; - private DefaultTableModel dtm; - private JButton del; + private final JTable jt; + private final DefaultTableModel dtm; + private final JButton del; /** * Constructor. diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java index 24ef7914e..46b5c96cb 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/MinusExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class MinusExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public MinusExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java index 606937e0b..926d6c119 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/MultiplyExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class MultiplyExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public MultiplyExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java index 6b957f6aa..908eec8d1 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/NumberExpression.java @@ -28,7 +28,7 @@ package com.iluwatar.interpreter; */ public class NumberExpression extends Expression { - private int number; + private final int number; public NumberExpression(int number) { this.number = number; diff --git a/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java b/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java index 1ce080259..38a8bb4af 100644 --- a/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java +++ b/interpreter/src/main/java/com/iluwatar/interpreter/PlusExpression.java @@ -28,8 +28,8 @@ package com.iluwatar.interpreter; */ public class PlusExpression extends Expression { - private Expression leftExpression; - private Expression rightExpression; + private final Expression leftExpression; + private final Expression rightExpression; public PlusExpression(Expression leftExpression, Expression rightExpression) { this.leftExpression = leftExpression; diff --git a/iterator/README.md b/iterator/README.md index 7f06a64b9..a98010c5a 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -36,7 +36,7 @@ The main class in our example is the treasure chest that contains items. ```java public class TreasureChest { - private List items; + private final List items; public TreasureChest() { items = List.of( @@ -64,7 +64,7 @@ public class TreasureChest { public class Item { private ItemType type; - private String name; + private final String name; public Item(ItemType type, String name) { this.setType(type); diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java index b3e0dc3d6..9f584cddc 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/BstIterator.java @@ -36,7 +36,7 @@ import java.util.NoSuchElementException; */ public class BstIterator> implements Iterator> { - private ArrayDeque> pathStack; + private final ArrayDeque> pathStack; public BstIterator(TreeNode root) { pathStack = new ArrayDeque<>(); diff --git a/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java index 87f16e96c..b0ec5f486 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java +++ b/iterator/src/main/java/com/iluwatar/iterator/bst/TreeNode.java @@ -31,7 +31,7 @@ package com.iluwatar.iterator.bst; */ public class TreeNode> { - private T val; + private final T val; private TreeNode left; private TreeNode right; diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/Item.java b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java index 82e66eb30..00d5625a8 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/Item.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/Item.java @@ -29,7 +29,7 @@ package com.iluwatar.iterator.list; public class Item { private ItemType type; - private String name; + private final String name; public Item(ItemType type, String name) { this.setType(type); diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java index f390c760f..8eb4a8e18 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChest.java @@ -32,7 +32,7 @@ import java.util.List; */ public class TreasureChest { - private List items; + private final List items; /** * Constructor. diff --git a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java index 90461c420..a309b4ece 100644 --- a/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java +++ b/iterator/src/main/java/com/iluwatar/iterator/list/TreasureChestItemIterator.java @@ -30,9 +30,9 @@ import com.iluwatar.iterator.Iterator; */ public class TreasureChestItemIterator implements Iterator { - private TreasureChest chest; + private final TreasureChest chest; private int idx; - private ItemType type; + private final ItemType type; /** * Constructor. diff --git a/layers/README.md b/layers/README.md index c3c56ad00..1e309f92b 100644 --- a/layers/README.md +++ b/layers/README.md @@ -79,7 +79,7 @@ public class CakeViewImpl implements View { private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class); - private CakeBakingService cakeBakingService; + private final CakeBakingService cakeBakingService; public CakeViewImpl(CakeBakingService cakeBakingService) { this.cakeBakingService = cakeBakingService; diff --git a/layers/src/main/java/com/iluwatar/layers/app/App.java b/layers/src/main/java/com/iluwatar/layers/app/App.java index afeb5ba50..e5a4f9995 100644 --- a/layers/src/main/java/com/iluwatar/layers/app/App.java +++ b/layers/src/main/java/com/iluwatar/layers/app/App.java @@ -80,7 +80,7 @@ import java.util.List; */ public class App { - private static CakeBakingService cakeBakingService = new CakeBakingServiceImpl(); + private static final CakeBakingService cakeBakingService = new CakeBakingServiceImpl(); /** * Application entry point. diff --git a/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java b/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java index 226b5bcea..14fee4dfa 100644 --- a/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java +++ b/layers/src/main/java/com/iluwatar/layers/service/CakeBakingServiceImpl.java @@ -52,7 +52,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class CakeBakingServiceImpl implements CakeBakingService { - private AbstractApplicationContext context; + private final AbstractApplicationContext context; public CakeBakingServiceImpl() { this.context = new ClassPathXmlApplicationContext("applicationContext.xml"); diff --git a/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java b/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java index 5fcaac776..a5246e7db 100644 --- a/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java +++ b/layers/src/main/java/com/iluwatar/layers/view/CakeViewImpl.java @@ -34,7 +34,7 @@ public class CakeViewImpl implements View { private static final Logger LOGGER = LoggerFactory.getLogger(CakeViewImpl.class); - private CakeBakingService cakeBakingService; + private final CakeBakingService cakeBakingService; public CakeViewImpl(CakeBakingService cakeBakingService) { this.cakeBakingService = cakeBakingService; diff --git a/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java b/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java index b707731d2..3c13966de 100644 --- a/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java +++ b/layers/src/test/java/com/iluwatar/layers/view/CakeViewImplTest.java @@ -90,7 +90,7 @@ public class CakeViewImplTest { private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java index 2854a7822..395dfb81c 100644 --- a/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java +++ b/lazy-loading/src/main/java/com/iluwatar/lazy/loading/Java8Holder.java @@ -55,7 +55,7 @@ public class Java8Holder { } } - if (!HeavyFactory.class.isInstance(heavy)) { + if (!(heavy instanceof HeavyFactory)) { heavy = new HeavyFactory(); } diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java index 3138427a3..3461bc8c0 100644 --- a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java +++ b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java @@ -31,7 +31,7 @@ import java.util.concurrent.BlockingQueue; */ public class TaskSet { - private BlockingQueue queue = new ArrayBlockingQueue<>(100); + private final BlockingQueue queue = new ArrayBlockingQueue<>(100); public void addTask(Task task) throws InterruptedException { queue.put(task); diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java index 7c63d95d2..935462037 100644 --- a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java +++ b/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java @@ -34,7 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class WorkCenter { private Worker leader; - private List workers = new CopyOnWriteArrayList<>(); + private final List workers = new CopyOnWriteArrayList<>(); /** * Create workers and set leader. diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java index 2466df256..4578752c3 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java @@ -40,7 +40,7 @@ public abstract class Master { private final int numOfWorkers; private final ArrayList workers; private int expectedNumResults; - private Hashtable allResultData; + private final Hashtable allResultData; private Result finalResult; Master(int numOfWorkers) { diff --git a/mediator/src/main/java/com/iluwatar/mediator/Action.java b/mediator/src/main/java/com/iluwatar/mediator/Action.java index 66e1f42c4..17613b5ab 100644 --- a/mediator/src/main/java/com/iluwatar/mediator/Action.java +++ b/mediator/src/main/java/com/iluwatar/mediator/Action.java @@ -1,52 +1,52 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.mediator; - -/** - * Action enumeration. - */ -public enum Action { - - HUNT("hunted a rabbit", "arrives for dinner"), - TALE("tells a tale", "comes to listen"), - GOLD("found gold", "takes his share of the gold"), - ENEMY("spotted enemies", "runs for cover"), - NONE("", ""); - - private String title; - private String description; - - Action(String title, String description) { - this.title = title; - this.description = description; - } - - public String getDescription() { - return description; - } - - public String toString() { - return title; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.mediator; + +/** + * Action enumeration. + */ +public enum Action { + + HUNT("hunted a rabbit", "arrives for dinner"), + TALE("tells a tale", "comes to listen"), + GOLD("found gold", "takes his share of the gold"), + ENEMY("spotted enemies", "runs for cover"), + NONE("", ""); + + private final String title; + private final String description; + + Action(String title, String description) { + this.title = title; + this.description = description; + } + + public String getDescription() { + return description; + } + + public String toString() { + return title; + } +} diff --git a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java index 951f8e166..01e855179 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/PartyMemberTest.java @@ -121,7 +121,7 @@ public class PartyMemberTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/memento/README.md b/memento/README.md index 8011dfc49..b8d95b72a 100644 --- a/memento/README.md +++ b/memento/README.md @@ -38,7 +38,7 @@ public enum StarType { SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( "dead star"), UNDEFINED(""); - private String title; + private final String title; StarType(String title) { this.title = title; diff --git a/memento/src/main/java/com/iluwatar/memento/StarType.java b/memento/src/main/java/com/iluwatar/memento/StarType.java index 507cd506b..339f05f9f 100644 --- a/memento/src/main/java/com/iluwatar/memento/StarType.java +++ b/memento/src/main/java/com/iluwatar/memento/StarType.java @@ -31,7 +31,7 @@ public enum StarType { SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( "dead star"), UNDEFINED(""); - private String title; + private final String title; StarType(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java index b1663df1f..2b7ca3999 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java @@ -30,7 +30,7 @@ public enum Fatigue { ALERT("alert"), TIRED("tired"), SLEEPING("sleeping"); - private String title; + private final String title; Fatigue(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java index e66608117..9acb49db4 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/GiantController.java @@ -28,8 +28,8 @@ package com.iluwatar.model.view.controller; */ public class GiantController { - private GiantModel giant; - private GiantView view; + private final GiantModel giant; + private final GiantView view; public GiantController(GiantModel giant, GiantView view) { this.giant = giant; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java index 30b3b2b90..a8346b9c7 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java @@ -30,7 +30,7 @@ public enum Health { HEALTHY("healthy"), WOUNDED("wounded"), DEAD("dead"); - private String title; + private final String title; Health(String title) { this.title = title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java index 3ced564cc..c61d2de79 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java @@ -30,7 +30,7 @@ public enum Nourishment { SATURATED("saturated"), HUNGRY("hungry"), STARVING("starving"); - private String title; + private final String title; Nourishment(String title) { this.title = title; diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java index a3e33f9dd..9d6421d13 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantViewTest.java @@ -75,7 +75,7 @@ public class GiantViewTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 77523ccaa..6c4df5231 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -48,37 +48,37 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti /** * The "OK" button for loading the file. */ - private JButton ok; + private final JButton ok; /** * The cancel button. */ - private JButton cancel; + private final JButton cancel; /** * The information label. */ - private JLabel info; + private final JLabel info; /** * The contents label. */ - private JLabel contents; + private final JLabel contents; /** * The text field for giving the name of the file that we want to open. */ - private JTextField input; + private final JTextField input; /** * A text area that will keep the contents of the file opened. */ - private JTextArea area; + private final JTextArea area; /** * The panel that will hold our widgets. */ - private JPanel panel; + private final JPanel panel; /** * The Presenter component that the frame will interact with. diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java index 35e1c0076..6fa95b125 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorPresenter.java @@ -41,7 +41,7 @@ public class FileSelectorPresenter implements Serializable { /** * The View component that the presenter interacts with. */ - private FileSelectorView view; + private final FileSelectorView view; /** * The Model component that the presenter interacts with. diff --git a/monad/src/main/java/com/iluwatar/monad/User.java b/monad/src/main/java/com/iluwatar/monad/User.java index 77766d1aa..8644c4c0a 100644 --- a/monad/src/main/java/com/iluwatar/monad/User.java +++ b/monad/src/main/java/com/iluwatar/monad/User.java @@ -1,66 +1,66 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.monad; - -/** - * User Definition. - */ -public class User { - - private String name; - private int age; - private Sex sex; - private String email; - - /** - * Constructor. - * - * @param name - name - * @param age - age - * @param sex - sex - * @param email - email address - */ - public User(String name, int age, Sex sex, String email) { - this.name = name; - this.age = age; - this.sex = sex; - this.email = email; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public Sex getSex() { - return sex; - } - - public String getEmail() { - return email; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.monad; + +/** + * User Definition. + */ +public class User { + + private final String name; + private final int age; + private final Sex sex; + private final String email; + + /** + * Constructor. + * + * @param name - name + * @param age - age + * @param sex - sex + * @param email - email address + */ + public User(String name, int age, Sex sex, String email) { + this.name = name; + this.age = age; + this.sex = sex; + this.email = email; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Sex getSex() { + return sex; + } + + public String getEmail() { + return email; + } +} diff --git a/multiton/README.md b/multiton/README.md index ec1429a8f..85ce3acf2 100644 --- a/multiton/README.md +++ b/multiton/README.md @@ -35,14 +35,14 @@ Nazgul is the multiton class. ```java public enum NazgulName { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } public final class Nazgul { - private static Map nazguls; + private static final Map nazguls; - private NazgulName name; + private final NazgulName name; static { nazguls = new ConcurrentHashMap<>(); diff --git a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java index f55f85aca..e08107eeb 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java +++ b/multiton/src/main/java/com/iluwatar/multiton/Nazgul.java @@ -31,9 +31,9 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class Nazgul { - private static Map nazguls; + private static final Map nazguls; - private NazgulName name; + private final NazgulName name; static { nazguls = new ConcurrentHashMap<>(); diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java index 5b5c48d66..ec20fbc97 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulEnum.java @@ -28,6 +28,6 @@ package com.iluwatar.multiton; */ public enum NazgulEnum { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } diff --git a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java index c7865dceb..76702c358 100644 --- a/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java +++ b/multiton/src/main/java/com/iluwatar/multiton/NazgulName.java @@ -28,6 +28,6 @@ package com.iluwatar.multiton; */ public enum NazgulName { - KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA; + KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA } diff --git a/null-object/README.md b/null-object/README.md index 0fce86f0e..5b943630e 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -101,7 +101,7 @@ public class NodeImpl implements Node { public final class NullNode implements Node { - private static NullNode instance = new NullNode(); + private static final NullNode instance = new NullNode(); private NullNode() { } diff --git a/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java b/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java index 9b28c249b..472a1a2fd 100644 --- a/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java +++ b/null-object/src/main/java/com/iluwatar/nullobject/NullNode.java @@ -30,7 +30,7 @@ package com.iluwatar.nullobject; */ public final class NullNode implements Node { - private static NullNode instance = new NullNode(); + private static final NullNode instance = new NullNode(); private NullNode() { } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java index 4ff30f524..3fe584425 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java @@ -141,7 +141,7 @@ public class TreeTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java b/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java index 4c704f6b1..308760ba9 100644 --- a/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java +++ b/object-mother/src/main/java/com/iluwatar/objectmother/Queen.java @@ -66,9 +66,6 @@ public class Queen implements Royalty { * @return A value which describes if the flirt was successful or not. */ public boolean getFlirted(King king) { - if (this.isFlirty && king.isHappy && !king.isDrunk) { - return true; - } - return false; + return this.isFlirty && king.isHappy && !king.isDrunk; } } diff --git a/object-pool/README.md b/object-pool/README.md index a8a20638c..34d216a02 100644 --- a/object-pool/README.md +++ b/object-pool/README.md @@ -36,7 +36,7 @@ Here's the basic Oliphaunt class. These are very expensive to create. ```java public class Oliphaunt { - private static AtomicInteger counter = new AtomicInteger(0); + private static final AtomicInteger counter = new AtomicInteger(0); private final int id; @@ -65,8 +65,8 @@ Next we present the Object Pool and more specifically Oliphaunt Pool. ```java public abstract class ObjectPool { - private Set available = new HashSet<>(); - private Set inUse = new HashSet<>(); + private final Set available = new HashSet<>(); + private final Set inUse = new HashSet<>(); protected abstract T create(); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java index b8ce3cc05..43ac5d873 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/ObjectPool.java @@ -33,8 +33,8 @@ import java.util.Set; */ public abstract class ObjectPool { - private Set available = new HashSet<>(); - private Set inUse = new HashSet<>(); + private final Set available = new HashSet<>(); + private final Set inUse = new HashSet<>(); protected abstract T create(); diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java index 42db07158..09dedbab0 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/Oliphaunt.java @@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class Oliphaunt { - private static AtomicInteger counter = new AtomicInteger(0); + private static final AtomicInteger counter = new AtomicInteger(0); private final int id; diff --git a/observer/README.md b/observer/README.md index edc72ae24..e329a657c 100644 --- a/observer/README.md +++ b/observer/README.md @@ -99,7 +99,7 @@ public class Weather { private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class); private WeatherType currentWeather; - private List observers; + private final List observers; public Weather() { observers = new ArrayList<>(); diff --git a/observer/src/main/java/com/iluwatar/observer/Weather.java b/observer/src/main/java/com/iluwatar/observer/Weather.java index 778858107..a0d80d6bc 100644 --- a/observer/src/main/java/com/iluwatar/observer/Weather.java +++ b/observer/src/main/java/com/iluwatar/observer/Weather.java @@ -37,7 +37,7 @@ public class Weather { private static final Logger LOGGER = LoggerFactory.getLogger(Weather.class); private WeatherType currentWeather; - private List observers; + private final List observers; public Weather() { observers = new ArrayList<>(); diff --git a/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java b/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java index b3d2bf1bc..132216d19 100644 --- a/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java +++ b/observer/src/test/java/com/iluwatar/observer/utils/InMemoryAppender.java @@ -35,7 +35,7 @@ import java.util.List; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java index 779458e05..22bc8a5fb 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumListPageTest { - private AlbumListPage albumListPage = new AlbumListPage(new WebClient()); + private final AlbumListPage albumListPage = new AlbumListPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java index 601093343..68c836bd3 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumPageTest { - private AlbumPage albumPage = new AlbumPage(new WebClient()); + private final AlbumPage albumPage = new AlbumPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java b/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java index 022f736ca..460bdcf96 100644 --- a/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java +++ b/page-object/src/test/java/com/iluwatar/pageobject/LoginPageTest.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; */ public class LoginPageTest { - private LoginPage loginPage = new LoginPage(new WebClient()); + private final LoginPage loginPage = new LoginPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java index d1b450a24..1acdd5ba5 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumListPageTest { - private AlbumListPage albumListPage = new AlbumListPage(new WebClient()); + private final AlbumListPage albumListPage = new AlbumListPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java index 8e694a592..ecde999c3 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class AlbumPageTest { - private AlbumPage albumPage = new AlbumPage(new WebClient()); + private final AlbumPage albumPage = new AlbumPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java index 89668882d..429b7fcc5 100644 --- a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java +++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class LoginPageTest { - private LoginPage loginPage = new LoginPage(new WebClient()); + private final LoginPage loginPage = new LoginPage(new WebClient()); @BeforeEach public void setUp() { diff --git a/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java b/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java index a61a3c429..11a4f23ca 100644 --- a/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java +++ b/partial-response/src/main/java/com/iluwatar/partialresponse/VideoResource.java @@ -30,8 +30,8 @@ import java.util.Map; * has all video details. */ public class VideoResource { - private FieldJsonMapper fieldJsonMapper; - private Map videos; + private final FieldJsonMapper fieldJsonMapper; + private final Map videos; /** * Constructor. diff --git a/poison-pill/README.md b/poison-pill/README.md index 823bb7df8..a6cd2fe80 100644 --- a/poison-pill/README.md +++ b/poison-pill/README.md @@ -80,7 +80,7 @@ public interface Message { public class SimpleMessage implements Message { - private Map headers = new HashMap<>(); + private final Map headers = new HashMap<>(); private String body; @Override diff --git a/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java b/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java index 8a7af515f..70d116c9f 100644 --- a/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java +++ b/poison-pill/src/main/java/com/iluwatar/poison/pill/SimpleMessage.java @@ -32,7 +32,7 @@ import java.util.Map; */ public class SimpleMessage implements Message { - private Map headers = new HashMap<>(); + private final Map headers = new HashMap<>(); private String body; @Override diff --git a/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java b/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java index 100565fbc..8365fca17 100644 --- a/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java +++ b/poison-pill/src/test/java/com/iluwatar/poison/pill/ConsumerTest.java @@ -92,7 +92,7 @@ public class ConsumerTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java index 695424695..d312cd34a 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/ImmutableStew.java @@ -1,50 +1,50 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.privateclassdata; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Immutable stew class, protected with Private Class Data pattern. - */ -public class ImmutableStew { - - private static final Logger LOGGER = LoggerFactory.getLogger(ImmutableStew.class); - - private StewData data; - - public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { - data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); - } - - /** - * Mix the stew. - */ - public void mix() { - LOGGER - .info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers", - data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers()); - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.privateclassdata; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Immutable stew class, protected with Private Class Data pattern. + */ +public class ImmutableStew { + + private static final Logger LOGGER = LoggerFactory.getLogger(ImmutableStew.class); + + private final StewData data; + + public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); + } + + /** + * Mix the stew. + */ + public void mix() { + LOGGER + .info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers", + data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers()); + } +} diff --git a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java index bcdaba3e9..1b0fd269b 100644 --- a/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java +++ b/private-class-data/src/main/java/com/iluwatar/privateclassdata/StewData.java @@ -1,61 +1,61 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.privateclassdata; - -/** - * Stew ingredients. - */ -public class StewData { - - private int numPotatoes; - private int numCarrots; - private int numMeat; - private int numPeppers; - - /** - * Constructor. - */ - public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { - this.numPotatoes = numPotatoes; - this.numCarrots = numCarrots; - this.numMeat = numMeat; - this.numPeppers = numPeppers; - } - - public int getNumPotatoes() { - return numPotatoes; - } - - public int getNumCarrots() { - return numCarrots; - } - - public int getNumMeat() { - return numMeat; - } - - public int getNumPeppers() { - return numPeppers; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.privateclassdata; + +/** + * Stew ingredients. + */ +public class StewData { + + private final int numPotatoes; + private final int numCarrots; + private final int numMeat; + private final int numPeppers; + + /** + * Constructor. + */ + public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + this.numPotatoes = numPotatoes; + this.numCarrots = numCarrots; + this.numMeat = numMeat; + this.numPeppers = numPeppers; + } + + public int getNumPotatoes() { + return numPotatoes; + } + + public int getNumCarrots() { + return numCarrots; + } + + public int getNumMeat() { + return numMeat; + } + + public int getNumPeppers() { + return numPeppers; + } +} diff --git a/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java b/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java index 6fbe638ae..bbcbc8021 100644 --- a/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java +++ b/private-class-data/src/test/java/com/iluwatar/privateclassdata/utils/InMemoryAppender.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java index 6991ec4d1..89f692282 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/Item.java @@ -28,9 +28,9 @@ package com.iluwatar.producer.consumer; */ public class Item { - private String producer; + private final String producer; - private int id; + private final int id; public Item(String producer, int id) { this.id = id; diff --git a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java index 674fb069a..118e3265d 100644 --- a/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java +++ b/producer-consumer/src/main/java/com/iluwatar/producer/consumer/ItemQueue.java @@ -31,7 +31,7 @@ import java.util.concurrent.LinkedBlockingQueue; */ public class ItemQueue { - private BlockingQueue queue; + private final BlockingQueue queue; public ItemQueue() { diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java index 1401460d6..8e2ed9474 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfBeast extends Beast { - private String helpType; + private final String helpType; public ElfBeast(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java index 4a7eea98f..42a54ca97 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfMage extends Mage { - private String helpType; + private final String helpType; public ElfMage(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java index 101cd5942..fb426a444 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java +++ b/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class ElfWarlord extends Warlord { - private String helpType; + private final String helpType; public ElfWarlord(String helpType) { this.helpType = helpType; diff --git a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java index eb84b2982..14516f3b4 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java +++ b/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java @@ -1,65 +1,65 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.prototype; - -/** - * Concrete factory class. - */ -public class HeroFactoryImpl implements HeroFactory { - - private Mage mage; - private Warlord warlord; - private Beast beast; - - /** - * Constructor. - */ - public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { - this.mage = mage; - this.warlord = warlord; - this.beast = beast; - } - - /** - * Create mage. - */ - public Mage createMage() { - return mage.copy(); - } - - /** - * Create warlord. - */ - public Warlord createWarlord() { - return warlord.copy(); - } - - /** - * Create beast. - */ - public Beast createBeast() { - return beast.copy(); - } - -} +/* + * The MIT License + * Copyright © 2014-2019 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.prototype; + +/** + * Concrete factory class. + */ +public class HeroFactoryImpl implements HeroFactory { + + private final Mage mage; + private final Warlord warlord; + private final Beast beast; + + /** + * Constructor. + */ + public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { + this.mage = mage; + this.warlord = warlord; + this.beast = beast; + } + + /** + * Create mage. + */ + public Mage createMage() { + return mage.copy(); + } + + /** + * Create warlord. + */ + public Warlord createWarlord() { + return warlord.copy(); + } + + /** + * Create beast. + */ + public Beast createBeast() { + return beast.copy(); + } + +} diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java index cf3dc18d8..91339887c 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcBeast extends Beast { - private String weapon; + private final String weapon; public OrcBeast(String weapon) { this.weapon = weapon; diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java index cb8239c3f..439e7f368 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcMage extends Mage { - private String weapon; + private final String weapon; public OrcMage(String weapon) { this.weapon = weapon; diff --git a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java index 39facc41e..a2ae31b4d 100644 --- a/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java +++ b/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java @@ -28,7 +28,7 @@ package com.iluwatar.prototype; */ public class OrcWarlord extends Warlord { - private String weapon; + private final String weapon; public OrcWarlord(String weapon) { this.weapon = weapon; diff --git a/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java b/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java index 2187c3300..173825288 100644 --- a/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java +++ b/proxy/src/test/java/com/iluwatar/proxy/utils/InMemoryAppender.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/reactor/src/main/java/com/iluwatar/reactor/app/App.java b/reactor/src/main/java/com/iluwatar/reactor/app/App.java index 3bd8176a6..f656eacf6 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/app/App.java +++ b/reactor/src/main/java/com/iluwatar/reactor/app/App.java @@ -89,8 +89,8 @@ import java.util.List; public class App { private NioReactor reactor; - private List channels = new ArrayList<>(); - private Dispatcher dispatcher; + private final List channels = new ArrayList<>(); + private final Dispatcher dispatcher; /** * Creates an instance of App which will use provided dispatcher for dispatching events on diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java index 13657cdb2..aba99d65c 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioDatagramChannel.java @@ -134,7 +134,7 @@ public class NioDatagramChannel extends AbstractNioChannel { */ public static class DatagramPacket { private SocketAddress sender; - private ByteBuffer data; + private final ByteBuffer data; private SocketAddress receiver; /** diff --git a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java index 1a0b17386..77e39a88d 100644 --- a/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java +++ b/reactor/src/main/java/com/iluwatar/reactor/framework/NioReactor.java @@ -228,8 +228,8 @@ public class NioReactor { * A command that changes the interested operations of the key provided. */ class ChangeKeyOpsCommand implements Runnable { - private SelectionKey key; - private int interestedOps; + private final SelectionKey key; + private final int interestedOps; public ChangeKeyOpsCommand(SelectionKey key, int interestedOps) { this.key = key; diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java index 6d705de2f..c54e62e58 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java @@ -34,11 +34,11 @@ public class Reader implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Reader.class); - private Lock readLock; + private final Lock readLock; - private String name; + private final String name; - private long readingTime; + private final long readingTime; /** * Create new Reader. diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java index 99c9b056b..932428b4f 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java @@ -59,8 +59,8 @@ public class ReaderWriterLock implements ReadWriteLock { */ private final Set globalMutex = new HashSet<>(); - private ReadLock readerLock = new ReadLock(); - private WriteLock writerLock = new WriteLock(); + private final ReadLock readerLock = new ReadLock(); + private final WriteLock writerLock = new WriteLock(); @Override public Lock readLock() { diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java index 7a971b28b..fbc8321f2 100644 --- a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java @@ -34,11 +34,11 @@ public class Writer implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(Writer.class); - private Lock writeLock; + private final Lock writeLock; - private String name; + private final String name; - private long writingTime; + private final long writingTime; /** * Create new Writer who writes for 250ms. diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java index c7e8bc02a..01a63d6c8 100644 --- a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/utils/InMemoryAppender.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; * InMemory Log Appender Util. */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender(Class clazz) { ((Logger) LoggerFactory.getLogger(clazz)).addAppender(this); diff --git a/repository/README.md b/repository/README.md index 09a9a2bba..ad603ee2b 100644 --- a/repository/README.md +++ b/repository/README.md @@ -157,9 +157,9 @@ public class PersonSpecifications { public static class AgeBetweenSpec implements Specification { - private int from; + private final int from; - private int to; + private final int to; public AgeBetweenSpec(int from, int to) { this.from = from; diff --git a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java index f91c0a6e1..919b746be 100644 --- a/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java +++ b/repository/src/main/java/com/iluwatar/repository/PersonSpecifications.java @@ -39,9 +39,9 @@ public class PersonSpecifications { */ public static class AgeBetweenSpec implements Specification { - private int from; + private final int from; - private int to; + private final int to; public AgeBetweenSpec(int from, int to) { this.from = from; diff --git a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java index 6b47cbe9a..9e2e1f4e1 100644 --- a/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/AnnotationBasedRepositoryTest.java @@ -48,12 +48,12 @@ public class AnnotationBasedRepositoryTest { @Resource private PersonRepository repository; - private Person peter = new Person("Peter", "Sagan", 17); - private Person nasta = new Person("Nasta", "Kuzminova", 25); - private Person john = new Person("John", "lawrence", 35); - private Person terry = new Person("Terry", "Law", 36); + private final Person peter = new Person("Peter", "Sagan", 17); + private final Person nasta = new Person("Nasta", "Kuzminova", 25); + private final Person john = new Person("John", "lawrence", 35); + private final Person terry = new Person("Terry", "Law", 36); - private List persons = List.of(peter, nasta, john, terry); + private final List persons = List.of(peter, nasta, john, terry); /** * Prepare data for test diff --git a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java index ad9587aca..77e2b3e35 100644 --- a/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java +++ b/repository/src/test/java/com/iluwatar/repository/RepositoryTest.java @@ -48,12 +48,12 @@ public class RepositoryTest { @Resource private PersonRepository repository; - private Person peter = new Person("Peter", "Sagan", 17); - private Person nasta = new Person("Nasta", "Kuzminova", 25); - private Person john = new Person("John", "lawrence", 35); - private Person terry = new Person("Terry", "Law", 36); + private final Person peter = new Person("Peter", "Sagan", 17); + private final Person nasta = new Person("Nasta", "Kuzminova", 25); + private final Person john = new Person("John", "lawrence", 35); + private final Person terry = new Person("Terry", "Law", 36); - private List persons = List.of(peter, nasta, john, terry); + private final List persons = List.of(peter, nasta, john, terry); /** * Prepare data for test diff --git a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java index 7bba17553..53caabea7 100644 --- a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java +++ b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/ClosableTest.java @@ -68,7 +68,7 @@ public class ClosableTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java b/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java index 966d0e3f0..1c4cf0383 100644 --- a/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java +++ b/role-object/src/main/java/com/iluwatar/roleobject/CustomerCore.java @@ -36,7 +36,7 @@ import java.util.Optional; */ public class CustomerCore extends Customer { - private Map roles; + private final Map roles; public CustomerCore() { roles = new HashMap<>(); diff --git a/role-object/src/main/java/com/iluwatar/roleobject/Role.java b/role-object/src/main/java/com/iluwatar/roleobject/Role.java index cbc6cc79b..a776178fb 100644 --- a/role-object/src/main/java/com/iluwatar/roleobject/Role.java +++ b/role-object/src/main/java/com/iluwatar/roleobject/Role.java @@ -34,7 +34,7 @@ public enum Role { Borrower(BorrowerRole.class), Investor(InvestorRole.class); - private Class typeCst; + private final Class typeCst; Role(Class typeCst) { this.typeCst = typeCst; diff --git a/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java b/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java index 818b59a14..506587c76 100644 --- a/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java +++ b/saga/src/main/java/com/iluwatar/saga/choreography/Saga.java @@ -33,7 +33,7 @@ import java.util.List; */ public class Saga { - private List chapters; + private final List chapters; private int pos; private boolean forward; private boolean finished; @@ -153,7 +153,7 @@ public class Saga { * outcoming parameter). */ public static class Chapter { - private String name; + private final String name; private ChapterResult result; private Object inValue; diff --git a/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java b/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java index a616ff4a5..c6bc7bc80 100644 --- a/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java +++ b/saga/src/main/java/com/iluwatar/saga/choreography/ServiceDiscoveryService.java @@ -32,7 +32,7 @@ import java.util.Optional; * The class representing a service discovery pattern. */ public class ServiceDiscoveryService { - private Map services; + private final Map services; /** * find any service. diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java b/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java index ef34ddb98..b04d22849 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/ChapterResult.java @@ -29,8 +29,8 @@ package com.iluwatar.saga.orchestration; * @param incoming value */ public class ChapterResult { - private K value; - private State state; + private final K value; + private final State state; public K getValue() { return value; diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java b/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java index aff3593f1..1b68d6cf7 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/Saga.java @@ -32,7 +32,7 @@ import java.util.List; */ public class Saga { - private List chapters; + private final List chapters; private Saga() { diff --git a/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java b/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java index dbc6e7eb5..f88efae52 100644 --- a/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java +++ b/saga/src/main/java/com/iluwatar/saga/orchestration/ServiceDiscoveryService.java @@ -31,7 +31,7 @@ import java.util.Optional; * The class representing a service discovery pattern. */ public class ServiceDiscoveryService { - private Map> services; + private final Map> services; public Optional find(String service) { return Optional.ofNullable(services.getOrDefault(service, null)); diff --git a/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java b/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java index 423b8e12e..f80a46fdc 100644 --- a/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java +++ b/saga/src/test/java/com/iluwatar/saga/orchestration/SagaOrchestratorInternallyTest.java @@ -34,7 +34,7 @@ import org.junit.Test; */ public class SagaOrchestratorInternallyTest { - private List records = new ArrayList<>(); + private final List records = new ArrayList<>(); @Test public void executeTest() { diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java index d94764dbe..1f4026b92 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/Fruit.java @@ -35,7 +35,7 @@ public class Fruit { ORANGE, APPLE, LEMON } - private FruitType type; + private final FruitType type; public Fruit(FruitType type) { this.type = type; diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java index 6b43c8100..5c2901efe 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitBowl.java @@ -31,7 +31,7 @@ import java.util.List; */ public class FruitBowl { - private List fruit = new ArrayList<>(); + private final List fruit = new ArrayList<>(); /** * Returns the amount of fruits left in bowl. diff --git a/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java index a360f955c..c74145610 100644 --- a/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java +++ b/semaphore/src/main/java/com/iluwatar/semaphore/FruitShop.java @@ -31,7 +31,7 @@ public class FruitShop { /** * The FruitBowl instances stored in the class. */ - private FruitBowl[] bowls = { + private final FruitBowl[] bowls = { new FruitBowl(), new FruitBowl(), new FruitBowl() @@ -40,7 +40,7 @@ public class FruitShop { /** * Access flags for each of the FruitBowl instances. */ - private boolean[] available = { + private final boolean[] available = { true, true, true @@ -49,7 +49,7 @@ public class FruitShop { /** * The Semaphore that controls access to the class resources. */ - private Semaphore semaphore; + private final Semaphore semaphore; /** * FruitShop constructor. diff --git a/servant/src/main/java/com/iluwatar/servant/App.java b/servant/src/main/java/com/iluwatar/servant/App.java index b68cb9aee..9c4591b05 100644 --- a/servant/src/main/java/com/iluwatar/servant/App.java +++ b/servant/src/main/java/com/iluwatar/servant/App.java @@ -39,8 +39,8 @@ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); - private static Servant jenkins = new Servant("Jenkins"); - private static Servant travis = new Servant("Travis"); + private static final Servant jenkins = new Servant("Jenkins"); + private static final Servant travis = new Servant("Travis"); /** * Program entry point. diff --git a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java b/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java index a13893f70..abe7c388d 100644 --- a/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java +++ b/serverless/src/main/java/com/iluwatar/serverless/baas/api/AbstractDynamoDbHandler.java @@ -40,7 +40,7 @@ import java.util.Map; public abstract class AbstractDynamoDbHandler { private DynamoDBMapper dynamoDbMapper; - private ObjectMapper objectMapper; + private final ObjectMapper objectMapper; public AbstractDynamoDbHandler() { this.initAmazonDynamoDb(); diff --git a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java b/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java index ef3909adc..a8c729163 100644 --- a/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java +++ b/serverless/src/test/java/com/iluwatar/serverless/baas/api/SavePersonApiHandlerTest.java @@ -52,7 +52,7 @@ public class SavePersonApiHandlerTest { @Mock private DynamoDBMapper dynamoDbMapper; - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Before public void setUp() { diff --git a/service-layer/README.md b/service-layer/README.md index 910eaeaea..5e8e49ea6 100644 --- a/service-layer/README.md +++ b/service-layer/README.md @@ -155,9 +155,9 @@ public interface MagicService { public class MagicServiceImpl implements MagicService { - private WizardDao wizardDao; - private SpellbookDao spellbookDao; - private SpellDao spellDao; + private final WizardDao wizardDao; + private final SpellbookDao spellbookDao; + private final SpellDao spellDao; public MagicServiceImpl(WizardDao wizardDao, SpellbookDao spellbookDao, SpellDao spellDao) { this.wizardDao = wizardDao; diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java index 962487bd9..cdcf926d0 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/magic/MagicServiceImpl.java @@ -37,9 +37,9 @@ import java.util.List; */ public class MagicServiceImpl implements MagicService { - private WizardDao wizardDao; - private SpellbookDao spellbookDao; - private SpellDao spellDao; + private final WizardDao wizardDao; + private final SpellbookDao spellbookDao; + private final SpellDao spellDao; /** * Constructor. diff --git a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java index 60f0f7c03..4e787d34c 100644 --- a/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java +++ b/service-locator/src/main/java/com/iluwatar/servicelocator/ServiceLocator.java @@ -31,7 +31,7 @@ package com.iluwatar.servicelocator; */ public final class ServiceLocator { - private static ServiceCache serviceCache = new ServiceCache(); + private static final ServiceCache serviceCache = new ServiceCache(); private ServiceLocator() { } diff --git a/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java b/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java index 4948c2a19..ce239c156 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java +++ b/sharding/src/main/java/com/iluwatar/sharding/LookupShardManager.java @@ -39,7 +39,7 @@ public class LookupShardManager extends ShardManager { private static final Logger LOGGER = LoggerFactory.getLogger(LookupShardManager.class); - private Map lookupMap = new HashMap<>(); + private final Map lookupMap = new HashMap<>(); @Override public int storeData(Data data) { diff --git a/sharding/src/main/java/com/iluwatar/sharding/Shard.java b/sharding/src/main/java/com/iluwatar/sharding/Shard.java index eb0814258..56037bc3a 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/Shard.java +++ b/sharding/src/main/java/com/iluwatar/sharding/Shard.java @@ -33,7 +33,7 @@ public class Shard { private final int id; - private Map dataStore; + private final Map dataStore; public Shard(final int id) { this.id = id; diff --git a/singleton/README.md b/singleton/README.md index 83f7fb355..60a103a3b 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -34,7 +34,7 @@ Joshua Bloch, Effective Java 2nd Edition p.18 ```java public enum EnumIvoryTower { - INSTANCE; + INSTANCE } ``` diff --git a/specification/README.md b/specification/README.md index 6e52bd2e7..6cc0c702f 100644 --- a/specification/README.md +++ b/specification/README.md @@ -146,7 +146,7 @@ public abstract class AbstractSelector implements Predicate { ```java public class ConjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs ConjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java index 6b359d8ac..214ae4562 100644 --- a/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java +++ b/specification/src/main/java/com/iluwatar/specification/creature/AbstractCreature.java @@ -33,11 +33,11 @@ import com.iluwatar.specification.property.Size; */ public abstract class AbstractCreature implements Creature { - private String name; - private Size size; - private Movement movement; - private Color color; - private Mass mass; + private final String name; + private final Size size; + private final Movement movement; + private final Color color; + private final Mass mass; /** * Constructor. diff --git a/specification/src/main/java/com/iluwatar/specification/property/Color.java b/specification/src/main/java/com/iluwatar/specification/property/Color.java index 6e96b5813..b3128054e 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Color.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Color.java @@ -30,7 +30,7 @@ public enum Color { DARK("dark"), LIGHT("light"), GREEN("green"), RED("red"); - private String title; + private final String title; Color(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Mass.java b/specification/src/main/java/com/iluwatar/specification/property/Mass.java index b2d6ddc66..e0e90aa06 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Mass.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Mass.java @@ -28,8 +28,8 @@ package com.iluwatar.specification.property; */ public class Mass { - private double value; - private String title; + private final double value; + private final String title; public Mass(double value) { this.value = value; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Movement.java b/specification/src/main/java/com/iluwatar/specification/property/Movement.java index f76b0584f..fcdcfae70 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Movement.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Movement.java @@ -30,7 +30,7 @@ public enum Movement { WALKING("walking"), SWIMMING("swimming"), FLYING("flying"); - private String title; + private final String title; Movement(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/property/Size.java b/specification/src/main/java/com/iluwatar/specification/property/Size.java index 27bc48024..c5ad5525c 100644 --- a/specification/src/main/java/com/iluwatar/specification/property/Size.java +++ b/specification/src/main/java/com/iluwatar/specification/property/Size.java @@ -30,7 +30,7 @@ public enum Size { SMALL("small"), NORMAL("normal"), LARGE("large"); - private String title; + private final String title; Size(String title) { this.title = title; diff --git a/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java index bd29aa260..661c8bceb 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/ConjunctionSelector.java @@ -30,7 +30,7 @@ import java.util.List; */ public class ConjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs ConjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java index 1fb38a43d..32dcf7e73 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/DisjunctionSelector.java @@ -30,7 +30,7 @@ import java.util.List; */ public class DisjunctionSelector extends AbstractSelector { - private List> leafComponents; + private final List> leafComponents; @SafeVarargs DisjunctionSelector(AbstractSelector... selectors) { diff --git a/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java b/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java index ad3063000..30302baa2 100644 --- a/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java +++ b/specification/src/main/java/com/iluwatar/specification/selector/NegationSelector.java @@ -30,7 +30,7 @@ package com.iluwatar.specification.selector; */ public class NegationSelector extends AbstractSelector { - private AbstractSelector component; + private final AbstractSelector component; NegationSelector(AbstractSelector selector) { this.component = selector; diff --git a/state/README.md b/state/README.md index 7be4d3351..a8dd2b5fc 100644 --- a/state/README.md +++ b/state/README.md @@ -43,7 +43,7 @@ public class PeacefulState implements State { private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); - private Mammoth mammoth; + private final Mammoth mammoth; public PeacefulState(Mammoth mammoth) { this.mammoth = mammoth; @@ -64,7 +64,7 @@ public class AngryState implements State { private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); - private Mammoth mammoth; + private final Mammoth mammoth; public AngryState(Mammoth mammoth) { this.mammoth = mammoth; diff --git a/state/src/main/java/com/iluwatar/state/AngryState.java b/state/src/main/java/com/iluwatar/state/AngryState.java index 8dc296c53..e105262b8 100644 --- a/state/src/main/java/com/iluwatar/state/AngryState.java +++ b/state/src/main/java/com/iluwatar/state/AngryState.java @@ -1,52 +1,52 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.state; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Angry state. - */ -public class AngryState implements State { - - private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); - - private Mammoth mammoth; - - public AngryState(Mammoth mammoth) { - this.mammoth = mammoth; - } - - @Override - public void observe() { - LOGGER.info("{} is furious!", mammoth); - } - - @Override - public void onEnterState() { - LOGGER.info("{} gets angry!", mammoth); - } - -} +/* + * The MIT License + * Copyright © 2014-2019 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.state; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Angry state. + */ +public class AngryState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(AngryState.class); + + private final Mammoth mammoth; + + public AngryState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is furious!", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} gets angry!", mammoth); + } + +} diff --git a/state/src/main/java/com/iluwatar/state/PeacefulState.java b/state/src/main/java/com/iluwatar/state/PeacefulState.java index ed83a0738..adf8be209 100644 --- a/state/src/main/java/com/iluwatar/state/PeacefulState.java +++ b/state/src/main/java/com/iluwatar/state/PeacefulState.java @@ -1,52 +1,52 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.state; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Peaceful state. - */ -public class PeacefulState implements State { - - private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); - - private Mammoth mammoth; - - public PeacefulState(Mammoth mammoth) { - this.mammoth = mammoth; - } - - @Override - public void observe() { - LOGGER.info("{} is calm and peaceful.", mammoth); - } - - @Override - public void onEnterState() { - LOGGER.info("{} calms down.", mammoth); - } - -} +/* + * The MIT License + * Copyright © 2014-2019 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.state; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Peaceful state. + */ +public class PeacefulState implements State { + + private static final Logger LOGGER = LoggerFactory.getLogger(PeacefulState.class); + + private final Mammoth mammoth; + + public PeacefulState(Mammoth mammoth) { + this.mammoth = mammoth; + } + + @Override + public void observe() { + LOGGER.info("{} is calm and peaceful.", mammoth); + } + + @Override + public void onEnterState() { + LOGGER.info("{} calms down.", mammoth); + } + +} diff --git a/state/src/test/java/com/iluwatar/state/MammothTest.java b/state/src/test/java/com/iluwatar/state/MammothTest.java index 15624c7ab..4cc6e0adb 100644 --- a/state/src/test/java/com/iluwatar/state/MammothTest.java +++ b/state/src/test/java/com/iluwatar/state/MammothTest.java @@ -96,7 +96,7 @@ public class MammothTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java b/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java index a0c7f84e6..5be38e471 100644 --- a/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java +++ b/step-builder/src/main/java/com/iluwatar/stepbuilder/CharacterStepBuilder.java @@ -105,7 +105,7 @@ public final class CharacterStepBuilder { private String wizardClass; private String weapon; private String spell; - private List abilities = new ArrayList<>(); + private final List abilities = new ArrayList<>(); @Override public ClassStep name(String name) { diff --git a/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java b/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java index cca82cefc..0b5a2d615 100644 --- a/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java +++ b/strategy/src/test/java/com/iluwatar/strategy/DragonSlayingStrategyTest.java @@ -91,7 +91,7 @@ public class DragonSlayingStrategyTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java index ba6030da4..95326eeec 100644 --- a/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java +++ b/template-method/src/test/java/com/iluwatar/templatemethod/StealingMethodTest.java @@ -146,7 +146,7 @@ public abstract class StealingMethodTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/throttling/README.md b/throttling/README.md index 48e1b1c78..257bce54a 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -32,8 +32,8 @@ Tenant class presents the clients of the API. CallsCount tracks the number of AP ```java public class Tenant { - private String name; - private int allowedCallsPerSecond; + private final String name; + private final int allowedCallsPerSecond; public Tenant(String name, int allowedCallsPerSecond, CallsCount callsCount) { if (allowedCallsPerSecond < 0) { @@ -56,7 +56,7 @@ public class Tenant { public final class CallsCount { private static final Logger LOGGER = LoggerFactory.getLogger(CallsCount.class); - private Map tenantCallsCount = new ConcurrentHashMap<>(); + private final Map tenantCallsCount = new ConcurrentHashMap<>(); public void addTenant(String tenantName) { tenantCallsCount.putIfAbsent(tenantName, new AtomicLong(0)); diff --git a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java index 8f8036286..abfd4d351 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java +++ b/throttling/src/main/java/com/iluwatar/throttling/CallsCount.java @@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory; public final class CallsCount { private static final Logger LOGGER = LoggerFactory.getLogger(CallsCount.class); - private Map tenantCallsCount = new ConcurrentHashMap<>(); + private final Map tenantCallsCount = new ConcurrentHashMap<>(); /** * Add a new tenant to 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 d94344428..5fe2c72db 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/Tenant.java +++ b/throttling/src/main/java/com/iluwatar/throttling/Tenant.java @@ -30,8 +30,8 @@ import java.security.InvalidParameterException; */ public class Tenant { - private String name; - private int allowedCallsPerSecond; + private final String name; + private final int allowedCallsPerSecond; /** * Constructor. diff --git a/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java b/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java index 6a328c3f0..786325237 100644 --- a/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java +++ b/throttling/src/test/java/com/iluwatar/throttling/B2BServiceTest.java @@ -34,7 +34,7 @@ import org.junit.jupiter.api.Test; */ public class B2BServiceTest { - private CallsCount callsCount = new CallsCount(); + private final CallsCount callsCount = new CallsCount(); @Test public void dummyCustomerApiTest() { diff --git a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java index c4e885896..4e5c14e0b 100644 --- a/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java +++ b/tls/src/main/java/com/iluwatar/tls/DateFormatCallable.java @@ -1,93 +1,93 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.tls; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.concurrent.Callable; -import java.util.stream.IntStream; -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} - * - * @author Thomas Bauer, 2017 - */ -public class DateFormatCallable implements Callable { - - private static final Logger LOGGER = LoggerFactory.getLogger(DateFormatCallable.class); - // class variables (members) - private ThreadLocal df; //TLTL - // 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" - */ - public DateFormatCallable(String inDateFormat, String inDateValue) { - final var idf = inDateFormat; //TLTL - this.df = ThreadLocal.withInitial(() -> { //TLTL - return new SimpleDateFormat(idf); //TLTL - }); //TLTL - // this.df = new SimpleDateFormat(inDateFormat); //NTLNTL - this.dateValue = inDateValue; - } - - @Override - public Result call() { - LOGGER.info(Thread.currentThread() + " started executing..."); - var result = new Result(); - - // Convert date value to date 5 times - IntStream.rangeClosed(1, 5).forEach(i -> { - try { - // this is the statement where it is important to have the - // 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 - } catch (Exception e) { - // write the Exception to a list and continue work - result.getExceptionList().add(e.getClass() + ": " + e.getMessage()); - } - }); - - LOGGER.info(Thread.currentThread() + " finished processing part of the thread"); - - return result; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.tls; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.concurrent.Callable; +import java.util.stream.IntStream; +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} + * + * @author Thomas Bauer, 2017 + */ +public class DateFormatCallable implements Callable { + + private static final Logger LOGGER = LoggerFactory.getLogger(DateFormatCallable.class); + // class variables (members) + private final ThreadLocal df; //TLTL + // private DateFormat df; //NTLNTL + + private final 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" + */ + public DateFormatCallable(String inDateFormat, String inDateValue) { + final var idf = inDateFormat; //TLTL + this.df = ThreadLocal.withInitial(() -> { //TLTL + return new SimpleDateFormat(idf); //TLTL + }); //TLTL + // this.df = new SimpleDateFormat(inDateFormat); //NTLNTL + this.dateValue = inDateValue; + } + + @Override + public Result call() { + LOGGER.info(Thread.currentThread() + " started executing..."); + var result = new Result(); + + // Convert date value to date 5 times + IntStream.rangeClosed(1, 5).forEach(i -> { + try { + // this is the statement where it is important to have the + // 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 + } catch (Exception e) { + // write the Exception to a list and continue work + result.getExceptionList().add(e.getClass() + ": " + e.getMessage()); + } + }); + + LOGGER.info(Thread.currentThread() + " finished processing part of the thread"); + + return result; + } +} diff --git a/tls/src/main/java/com/iluwatar/tls/Result.java b/tls/src/main/java/com/iluwatar/tls/Result.java index c98a07b91..38dc197cf 100644 --- a/tls/src/main/java/com/iluwatar/tls/Result.java +++ b/tls/src/main/java/com/iluwatar/tls/Result.java @@ -1,65 +1,65 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -/* - * Fiducia IT AG, All rights reserved. Use is subject to license terms. - */ - -package com.iluwatar.tls; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * Result object that will be returned by the Callable {@link DateFormatCallable} used in {@link - * App}. - * - * @author Thomas Bauer, 2017 - */ -public class Result { - // A list to collect the date values created in one thread - private List dateList = new ArrayList<>(); - - // 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() { - return dateList; - } - - /** - * Get list of exceptions thrown within a thread execution. - * - * @return List of exceptions thrown within an thread execution - */ - public List getExceptionList() { - return exceptionList; - } -} +/* + * The MIT License + * Copyright © 2014-2019 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. + */ + +/* + * Fiducia IT AG, All rights reserved. Use is subject to license terms. + */ + +package com.iluwatar.tls; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Result object that will be returned by the Callable {@link DateFormatCallable} used in {@link + * App}. + * + * @author Thomas Bauer, 2017 + */ +public class Result { + // A list to collect the date values created in one thread + private final List dateList = new ArrayList<>(); + + // A list to collect Exceptions thrown in one threads (should be none in + // this example) + private final 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() { + return dateList; + } + + /** + * Get list of exceptions thrown within a thread execution. + * + * @return List of exceptions thrown within an thread execution + */ + public List getExceptionList() { + return exceptionList; + } +} diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java index 48e5854a3..5338829d0 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTest.java @@ -66,18 +66,18 @@ public class DateFormatCallableTest { /** * Expected number of date values in the date value list created by the run of DateFormatRunnalbe */ - private int expectedCounterDateValues = 5; + private final int expectedCounterDateValues = 5; /** * Expected number of exceptions in the exception list created by the run of DateFormatRunnalbe. */ - private int expectedCounterExceptions = 0; + private final int expectedCounterExceptions = 0; /** * Expected content of the list containing the date values created by the run of * DateFormatRunnalbe */ - private List expectedDateValues = + private final List expectedDateValues = List.of("15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015"); /** diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java index 8b02faf0b..7b3d6b4ad 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestIncorrectDateFormat.java @@ -54,18 +54,18 @@ public class DateFormatCallableTestIncorrectDateFormat { /** * Expected number of date values in the date value list created by the run of DateFormatRunnalbe */ - private int expectedCounterDateValues = 0; + private final int expectedCounterDateValues = 0; /** * Expected number of exceptions in the exception list created by the run of DateFormatRunnalbe. */ - private int expectedCounterExceptions = 5; + private final int expectedCounterExceptions = 5; /** * Expected content of the list containing the exceptions created by the run of * DateFormatRunnalbe */ - private List expectedExceptions = List.of( + private final List expectedExceptions = List.of( "class java.text.ParseException: Unparseable date: \"15.12.2015\"", "class java.text.ParseException: Unparseable date: \"15.12.2015\"", "class java.text.ParseException: Unparseable date: \"15.12.2015\"", diff --git a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java index c0e8e1844..b3328d4c5 100644 --- a/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java +++ b/tls/src/test/java/com/iluwatar/tls/DateFormatCallableTestMultiThread.java @@ -55,7 +55,7 @@ public class DateFormatCallableTestMultiThread { * Result object given back by DateFormatCallable, one for each thread -- Array with converted * date values -- Array with thrown exceptions */ - private static Result[] result = new Result[4]; + private static final Result[] result = new Result[4]; /** * The date values created by the run of of DateFormatRunnalbe. List will be filled in the setup() @@ -66,22 +66,22 @@ public class DateFormatCallableTestMultiThread { /* nothing needed here */ } - private static List[] createdDateValues = new StringArrayList[4]; + private static final List[] createdDateValues = new StringArrayList[4]; /** * Expected number of date values in the date value list created by each thread */ - private int expectedCounterDateValues = 5; + private final int expectedCounterDateValues = 5; /** * Expected number of exceptions in the exception list created by each thread */ - private int expectedCounterExceptions = 0; + private final int expectedCounterExceptions = 0; /** * Expected content of the list containing the date values created by each thread */ - private List expectedDateValues = + private final List expectedDateValues = List.of("15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015", "15.11.2015"); /** diff --git a/tolerant-reader/README.md b/tolerant-reader/README.md index a62e5f4cd..922de90de 100644 --- a/tolerant-reader/README.md +++ b/tolerant-reader/README.md @@ -35,10 +35,10 @@ public class RainbowFish implements Serializable { private static final long serialVersionUID = 1L; - private String name; - private int age; - private int lengthMeters; - private int weightTons; + private final String name; + private final int age; + private final int lengthMeters; + private final int weightTons; /** * Constructor. 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 775fc98f7..7529435fe 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFish.java @@ -32,10 +32,10 @@ public class RainbowFish implements Serializable { private static final long serialVersionUID = 1L; - private String name; - private int age; - private int lengthMeters; - private int weightTons; + private final String name; + private final int age; + private final int lengthMeters; + private final int weightTons; /** * Constructor. diff --git a/twin/src/test/java/com/iluwatar/twin/BallItemTest.java b/twin/src/test/java/com/iluwatar/twin/BallItemTest.java index 568c1d7b0..18aba2bed 100644 --- a/twin/src/test/java/com/iluwatar/twin/BallItemTest.java +++ b/twin/src/test/java/com/iluwatar/twin/BallItemTest.java @@ -108,7 +108,7 @@ public class BallItemTest { * Logging Appender Implementation */ public class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java index e70acbf9e..80054a5fb 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java @@ -56,7 +56,7 @@ public class App { * * @param args command line args */ - public static void main(String[] args) throws FileNotFoundException, IOException, ParseException { + public static void main(String[] args) throws IOException, ParseException { var givenTime = 50; //50ms var toWin = 500; //points var pointsWon = 0; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java index ec41dc6cd..88bfe0ada 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java @@ -38,7 +38,7 @@ public class Candy { Candy parent; String parentName; private int points; - private Type type; + private final Type type; Candy(String name, String parentName, Type type, int points) { this.name = name; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java index 553458a6d..f33640f2a 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java @@ -77,7 +77,7 @@ public class CellPool { pointer++; } - Candy[] assignRandomCandytypes() throws FileNotFoundException, IOException, ParseException { + Candy[] assignRandomCandytypes() throws IOException, ParseException { var jp = new JsonParser(); jp.parse(); var randomCode = new Candy[jp.candies.size() - 2]; //exclude generic types 'fruit' and 'candy' diff --git a/unit-of-work/README.md b/unit-of-work/README.md index 1f6c7c5b2..590f718d3 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -79,8 +79,8 @@ public interface IUnitOfWork { public class StudentRepository implements IUnitOfWork { private static final Logger LOGGER = LoggerFactory.getLogger(StudentRepository.class); - private Map> context; - private StudentDatabase studentDatabase; + private final Map> context; + private final StudentDatabase studentDatabase; public StudentRepository(Map> context, StudentDatabase studentDatabase) { this.context = context; diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java index ee5fc613d..73c1068b3 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java @@ -35,8 +35,8 @@ import org.slf4j.LoggerFactory; public class StudentRepository implements IUnitOfWork { private static final Logger LOGGER = LoggerFactory.getLogger(StudentRepository.class); - private Map> context; - private StudentDatabase studentDatabase; + private final Map> context; + private final StudentDatabase studentDatabase; /** * Constructor. diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/World.java b/update-method/src/main/java/com/iluwatar/updatemethod/World.java index 8cabead56..5b99050c8 100644 --- a/update-method/src/main/java/com/iluwatar/updatemethod/World.java +++ b/update-method/src/main/java/com/iluwatar/updatemethod/World.java @@ -87,7 +87,8 @@ public class World { * Render the next frame. Here we do nothing since it is not related to the * pattern. */ - private void render() {} + private void render() { + } /** * Run game loop. diff --git a/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java index 740be76b1..453718875 100644 --- a/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java +++ b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java @@ -103,10 +103,7 @@ public class HeroStat { if (luck != other.luck) { return false; } - if (strength != other.strength) { - return false; - } - return true; + return strength == other.strength; } // The clone() method should not be public. Just don't override it. diff --git a/visitor/README.md b/visitor/README.md index 3b4be5082..c97e97120 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -32,7 +32,7 @@ Given the army unit example from above, we first have the Unit and UnitVisitor b ```java public abstract class Unit { - private Unit[] children; + private final Unit[] children; public Unit(Unit... children) { this.children = children; diff --git a/visitor/src/main/java/com/iluwatar/visitor/Unit.java b/visitor/src/main/java/com/iluwatar/visitor/Unit.java index c890884b3..3597c4d60 100644 --- a/visitor/src/main/java/com/iluwatar/visitor/Unit.java +++ b/visitor/src/main/java/com/iluwatar/visitor/Unit.java @@ -1,45 +1,45 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.visitor; - -import java.util.Arrays; - -/** - * Interface for the nodes in hierarchy. - */ -public abstract class Unit { - - private Unit[] children; - - public Unit(Unit... children) { - this.children = children; - } - - /** - * Accept visitor. - */ - public void accept(UnitVisitor visitor) { - Arrays.stream(children).forEach(child -> child.accept(visitor)); - } -} +/* + * The MIT License + * Copyright © 2014-2019 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.visitor; + +import java.util.Arrays; + +/** + * Interface for the nodes in hierarchy. + */ +public abstract class Unit { + + private final Unit[] children; + + public Unit(Unit... children) { + this.children = children; + } + + /** + * Accept visitor. + */ + public void accept(UnitVisitor visitor) { + Arrays.stream(children).forEach(child -> child.accept(visitor)); + } +} diff --git a/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java b/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java index 146ee22f8..fd2f1cb76 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java +++ b/visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java @@ -123,7 +123,7 @@ public abstract class VisitorTest { } private class InMemoryAppender extends AppenderBase { - private List log = new LinkedList<>(); + private final List log = new LinkedList<>(); public InMemoryAppender() { ((Logger) LoggerFactory.getLogger("root")).addAppender(this); From 8364b289b4c6bcfbee5df4f694f7f8bc3f59f58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 21:38:40 +0300 Subject: [PATCH 154/285] #590 explanation for Abstract Document --- abstract-document/README.md | 175 +++++++++++++++++- .../abstractdocument/domain/HasParts.java | 1 - .../abstractdocument/domain/HasPrice.java | 1 - .../abstractdocument/domain/HasType.java | 1 - 4 files changed, 168 insertions(+), 10 deletions(-) diff --git a/abstract-document/README.md b/abstract-document/README.md index 15f5c6c85..d985cff2b 100644 --- a/abstract-document/README.md +++ b/abstract-document/README.md @@ -9,21 +9,182 @@ tags: --- ## Intent -Achieve flexibility of untyped languages and keep the type-safety + +Use dynamic properties and achieve flexibility of untyped languages while keeping type-safety. + +## Explanation + +The Abstract Document pattern enables handling additional, non-static properties. This pattern +uses concept of traits to enable type safety and separate properties of different classes into +set of interfaces. + +Real world example + +> Consider a car that consists of multiple parts. However we don't know if the specific car really has all the parts, or just some of them. Our cars are dynamic and extremely flexible. + +In plain words + +> Abstract Document pattern allows attaching properties to objects without them knowing about it. + +Wikipedia says + +> An object-oriented structural design pattern for organizing objects in loosely typed key-value stores and exposing +the data using typed views. The purpose of the pattern is to achieve a high degree of flexibility between components +in a strongly typed language where new properties can be added to the object-tree on the fly, without losing the +support of type-safety. The pattern makes use of traits to separate different properties of a class into different +interfaces. + +**Programmatic Example** + +Let's first define the base classes `Document` and `AbstractDocument`. They basically make the object hold a property +map and any amount of child objects. + +```java +public interface Document { + + Void put(String key, Object value); + + Object get(String key); + + Stream children(String key, Function, T> constructor); +} + +public abstract class AbstractDocument implements Document { + + private final Map properties; + + protected AbstractDocument(Map properties) { + Objects.requireNonNull(properties, "properties map is required"); + this.properties = properties; + } + + @Override + public Void put(String key, Object value) { + properties.put(key, value); + return null; + } + + @Override + public Object get(String key) { + return properties.get(key); + } + + @Override + public Stream children(String key, Function, T> constructor) { + return Stream.ofNullable(get(key)) + .filter(Objects::nonNull) + .map(el -> (List>) el) + .findAny() + .stream() + .flatMap(Collection::stream) + .map(constructor); + } + ... +} +``` +Next we define an enum `Property` and a set of interfaces for type, price, model and parts. This allows us to create +static looking interface to our `Car` class. + +```java +public enum Property { + + PARTS, TYPE, PRICE, MODEL +} + +public interface HasType extends Document { + + default Optional getType() { + return Optional.ofNullable((String) get(Property.TYPE.toString())); + } +} + +public interface HasPrice extends Document { + + default Optional getPrice() { + return Optional.ofNullable((Number) get(Property.PRICE.toString())); + } +} +public interface HasModel extends Document { + + default Optional getModel() { + return Optional.ofNullable((String) get(Property.MODEL.toString())); + } +} + +public interface HasParts extends Document { + + default Stream getParts() { + return children(Property.PARTS.toString(), Part::new); + } +} +``` + +Now we are ready to introduce the `Car`. + +```java +public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts { + + public Car(Map properties) { + super(properties); + } +} +``` + +And finally here's how we construct and use the `Car` in a full example. + +```java + LOGGER.info("Constructing parts and car"); + + var wheelProperties = Map.of( + Property.TYPE.toString(), "wheel", + Property.MODEL.toString(), "15C", + Property.PRICE.toString(), 100L); + + var doorProperties = Map.of( + Property.TYPE.toString(), "door", + Property.MODEL.toString(), "Lambo", + Property.PRICE.toString(), 300L); + + var carProperties = Map.of( + Property.MODEL.toString(), "300SL", + Property.PRICE.toString(), 10000L, + Property.PARTS.toString(), List.of(wheelProperties, doorProperties)); + + var car = new Car(carProperties); + + LOGGER.info("Here is our car:"); + LOGGER.info("-> model: {}", car.getModel().orElseThrow()); + LOGGER.info("-> price: {}", car.getPrice().orElseThrow()); + LOGGER.info("-> parts: "); + car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}", + p.getType().orElse(null), + p.getModel().orElse(null), + p.getPrice().orElse(null)) + ); + + // Constructing parts and car + // Here is our car: + // model: 300SL + // price: 10000 + // parts: + // wheel/15C/100 + // door/Lambo/300 +``` ## Class diagram + ![alt text](./etc/abstract-document.png "Abstract Document Traits and Domain") - ## Applicability + Use the Abstract Document Pattern when -* there is a need to add new properties on the fly -* you want a flexible way to organize domain in tree like structure -* you want more loosely coupled system - +* There is a need to add new properties on the fly +* You want a flexible way to organize domain in tree like structure +* You want more loosely coupled system ## Credits - +`` * [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern) * [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf) +* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492) diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java index 8ecfa85fb..54f308ccf 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java @@ -32,7 +32,6 @@ import java.util.stream.Stream; */ public interface HasParts extends Document { - default Stream getParts() { return children(Property.PARTS.toString(), Part::new); } diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java index 9a95f2a51..a50c725c3 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java @@ -32,7 +32,6 @@ import java.util.Optional; */ public interface HasPrice extends Document { - default Optional getPrice() { return Optional.ofNullable((Number) get(Property.PRICE.toString())); } diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java index b1d5bd6b5..2722564d5 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java @@ -32,7 +32,6 @@ import java.util.Optional; */ public interface HasType extends Document { - default Optional getType() { return Optional.ofNullable((String) get(Property.TYPE.toString())); } From 55bb1f11e0536a42196b1e9dde855b6eeabea237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 30 Jul 2020 21:57:07 +0300 Subject: [PATCH 155/285] #590 fix typo --- abstract-document/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abstract-document/README.md b/abstract-document/README.md index d985cff2b..cbb35cee8 100644 --- a/abstract-document/README.md +++ b/abstract-document/README.md @@ -184,7 +184,7 @@ Use the Abstract Document Pattern when * You want more loosely coupled system ## Credits -`` + * [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern) * [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf) * [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492) From 29f799c815379808624d6662b9172b2e2f3b3395 Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Fri, 31 Jul 2020 22:50:48 -0400 Subject: [PATCH 156/285] Corrected assertEquals order for expected, actual. --- .../java/com/iluwatar/arrangeactassert/CashAAATest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java index d7841843d..115dd3a11 100644 --- a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAAATest.java @@ -60,7 +60,7 @@ public class CashAAATest { //Act cash.plus(4); //Assert - assertEquals(cash.count(), 7); + assertEquals(7, cash.count()); } @Test @@ -71,7 +71,7 @@ public class CashAAATest { var result = cash.minus(5); //Assert assertTrue(result); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); } @Test @@ -82,7 +82,7 @@ public class CashAAATest { var result = cash.minus(6); //Assert assertFalse(result); - assertEquals(cash.count(), 1); + assertEquals(1, cash.count()); } @Test @@ -94,6 +94,6 @@ public class CashAAATest { var result = cash.minus(3); //Assert assertTrue(result); - assertEquals(cash.count(), 8); + assertEquals(8, cash.count()); } } From fb6507ceda06675fd910a736bcc35edd752321cb Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Fri, 31 Jul 2020 22:52:23 -0400 Subject: [PATCH 157/285] Corrected assertEquals order for expected, actual. --- .../com/iluwatar/arrangeactassert/CashAntiAAATest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java index 3f8c33d5e..564b923e7 100644 --- a/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java +++ b/arrange-act-assert/src/test/java/com/iluwatar/arrangeactassert/CashAntiAAATest.java @@ -44,16 +44,16 @@ public class CashAntiAAATest { var cash = new Cash(3); //test plus cash.plus(4); - assertEquals(cash.count(), 7); + assertEquals(7, cash.count()); //test minus cash = new Cash(8); assertTrue(cash.minus(5)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); assertFalse(cash.minus(6)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); //test update cash.plus(5); assertTrue(cash.minus(5)); - assertEquals(cash.count(), 3); + assertEquals(3, cash.count()); } } From 41020982de25493497b1976c19929e4e49b200e0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:41:47 +0000 Subject: [PATCH 158/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3c815cb3..401a92103 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-114-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-115-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -239,6 +239,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 +
Matt Dolan

💻 From 7908d38604403eb3e6459d8e8a15b984f32ceab5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:41:48 +0000 Subject: [PATCH 159/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9a536d34d..50f6363e0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1038,6 +1038,15 @@ "contributions": [ "translation" ] + }, + { + "login": "charlesfinley", + "name": "Matt Dolan", + "avatar_url": "https://avatars1.githubusercontent.com/u/6307904?v=4", + "profile": "https://github.com/charlesfinley", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 15eb49e5743a80d588f8b562f2a23fd7151d4f47 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:07:20 +0000 Subject: [PATCH 160/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 401a92103..13a32d769 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-115-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-116-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -240,6 +240,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍
Matt Dolan

💻 +
Manan

👀 From 0a2c87d49adbde9b96866a93f1886ff5764ce753 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:07:21 +0000 Subject: [PATCH 161/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 50f6363e0..8045f7326 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1047,6 +1047,15 @@ "contributions": [ "code" ] + }, + { + "login": "MananS77", + "name": "Manan", + "avatar_url": "https://avatars3.githubusercontent.com/u/21033516?v=4", + "profile": "https://github.com/MananS77", + "contributions": [ + "review" + ] } ], "contributorsPerLine": 4, From e4473e5c882f5496eb89959aa453e1b9aca2510f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:45:38 +0000 Subject: [PATCH 162/285] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13a32d769..feb64a1b5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-116-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-117-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -242,6 +242,9 @@ This project is licensed under the terms of the MIT license.
Matt Dolan

💻
Manan

👀 + +
Nishant Arora

💻 + From d41077f355a4f52c911220e5f001af377db851dd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 08:45:39 +0000 Subject: [PATCH 163/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8045f7326..58d3e4c5d 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1056,6 +1056,15 @@ "contributions": [ "review" ] + }, + { + "login": "nishant", + "name": "Nishant Arora", + "avatar_url": "https://avatars2.githubusercontent.com/u/15331971?v=4", + "profile": "https://github.com/nishant", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 27c40826de7fa6c059d51775f026e59b24333410 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 09:48:23 +0000 Subject: [PATCH 164/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index feb64a1b5..21939391e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-117-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-118-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -244,6 +244,7 @@ This project is licensed under the terms of the MIT license.
Nishant Arora

💻 +
Peeyush

💻 From 38791a6a661f080be6cc1b3e48f742de993c7599 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2020 09:48:24 +0000 Subject: [PATCH 165/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 58d3e4c5d..80c2288b6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1065,6 +1065,15 @@ "contributions": [ "code" ] + }, + { + "login": "raja-peeyush-kumar-singh", + "name": "Peeyush", + "avatar_url": "https://avatars0.githubusercontent.com/u/5496024?v=4", + "profile": "https://github.com/raja-peeyush-kumar-singh", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 7ac8eba43467c9fc85a2b5a61516fccef20a8403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:18:32 +0300 Subject: [PATCH 166/285] #590 explanation for Acyclic Visitor --- acyclic-visitor/README.md | 126 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/acyclic-visitor/README.md b/acyclic-visitor/README.md index f293e4393..19e886505 100644 --- a/acyclic-visitor/README.md +++ b/acyclic-visitor/README.md @@ -9,12 +9,126 @@ tags: --- ## Intent -Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the troublesome dependency cycles that are inherent to the GOF VISITOR Pattern. + +Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating +the troublesome dependency cycles that are inherent to the GoF Visitor Pattern. + +## Explanation + +Real world example + +> We have a hierarchy of modem classes. The modems in this hierarchy need to be visited by an external algorithm based +> on filtering criteria (is it Unix or DOS compatible modem). + +In plain words + +> Acyclic Visitor allows functions to be added to existing class hierarchies without modifying the hierarchies. + +[WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor) says + +> The Acyclic Visitor pattern allows new functions to be added to existing class hierarchies without affecting those +> hierarchies, and without creating the dependency cycles that are inherent to the GangOfFour VisitorPattern. + +**Programmatic Example** + +Here's the `Modem` hierarchy. + +```java +public abstract class Modem { + public abstract void accept(ModemVisitor modemVisitor); +} + +public class Zoom extends Modem { + ... + @Override + public void accept(ModemVisitor modemVisitor) { + if (modemVisitor instanceof ZoomVisitor) { + ((ZoomVisitor) modemVisitor).visit(this); + } else { + LOGGER.info("Only ZoomVisitor is allowed to visit Zoom modem"); + } + } +} + +public class Hayes extends Modem { + ... + @Override + public void accept(ModemVisitor modemVisitor) { + if (modemVisitor instanceof HayesVisitor) { + ((HayesVisitor) modemVisitor).visit(this); + } else { + LOGGER.info("Only HayesVisitor is allowed to visit Hayes modem"); + } + } +} +``` + +Next we introduce the `ModemVisitor` hierarchy. + +```java +public interface ModemVisitor { +} + +public interface HayesVisitor extends ModemVisitor { + void visit(Hayes hayes); +} + +public interface ZoomVisitor extends ModemVisitor { + void visit(Zoom zoom); +} + +public interface AllModemVisitor extends ZoomVisitor, HayesVisitor { +} + +public class ConfigureForDosVisitor implements AllModemVisitor { + ... + @Override + public void visit(Hayes hayes) { + LOGGER.info(hayes + " used with Dos configurator."); + } + @Override + public void visit(Zoom zoom) { + LOGGER.info(zoom + " used with Dos configurator."); + } +} + +public class ConfigureForUnixVisitor implements ZoomVisitor { + ... + @Override + public void visit(Zoom zoom) { + LOGGER.info(zoom + " used with Unix configurator."); + } +} +``` + +Finally here are the visitors in action. + +```java + var conUnix = new ConfigureForUnixVisitor(); + var conDos = new ConfigureForDosVisitor(); + var zoom = new Zoom(); + var hayes = new Hayes(); + hayes.accept(conDos); + zoom.accept(conDos); + hayes.accept(conUnix); + zoom.accept(conUnix); +``` + +Program output: + +``` + // Hayes modem used with Dos configurator. + // Zoom modem used with Dos configurator. + // Only HayesVisitor is allowed to visit Hayes modem + // Zoom modem used with Unix configurator. +``` ## Class diagram + ![alt text](./etc/acyclic-visitor.png "Acyclic Visitor") ## Applicability + This pattern can be used: * When you need to add a new function to an existing hierarchy without the need to alter or affect that hierarchy. @@ -24,6 +138,7 @@ This pattern can be used: * When the recompilation, relinking, retesting or redistribution of the derivatives of Element is very expensive. ## Consequences + The good: * No dependency cycles between class hierarchies. @@ -32,11 +147,14 @@ The good: The bad: -* Violates the principle of least surprise or Liskov's Substitution principle by showing that it can accept all visitors but actually only being interested in particular visitors. +* Violates [Liskov's Substitution Principle](https://java-design-patterns.com/principles/#liskov-substitution-principle) by showing that it can accept all visitors but actually only being interested in particular visitors. * Parallel hierarchy of visitors has to be created for all members in visitable class hierarchy. ## Related patterns -* [Visitor Pattern](../visitor/) + +* [Visitor Pattern](https://java-design-patterns.com/patterns/visitor/) ## Credits -* [Acyclic Visitor](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf) + +* [Acyclic Visitor by Robert C. Martin](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf) +* [Acyclic Visitor in WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor) From 6a8297598e93195be7aa401af8f528768bef6f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:19:09 +0300 Subject: [PATCH 167/285] #1047 remove module infos --- .../abstractdocument/module-info.java | 26 ----------------- .../iluwatar/abstractfactory/module-info.java | 26 ----------------- .../iluwatar/acyclicvisitor/module-info.java | 26 ----------------- .../business/delegate/module-info.java | 26 ----------------- .../com/iluwatar/callback/module-info.java | 26 ----------------- .../java/com/iluwatar/chain/module-info.java | 26 ----------------- .../collectionpipeline/module-info.java | 26 ----------------- .../com/iluwatar/command/module-info.java | 26 ----------------- .../com/iluwatar/composite/module-info.java | 26 ----------------- .../com/iluwatar/converter/module-info.java | 26 ----------------- .../java/com/iluwatar/dao/module-info.java | 29 ------------------- .../com/iluwatar/datamapper/module-info.java | 26 ----------------- .../iluwatar/datatransfer/module-info.java | 26 ----------------- .../com/iluwatar/decorator/module-info.java | 26 ----------------- .../com/iluwatar/delegation/module-info.java | 26 ----------------- .../com/iluwatar/dirtyflag/module-info.java | 26 ----------------- .../doublechecked/locking/module-info.java | 26 ----------------- .../iluwatar/doubledispatch/module-info.java | 26 ----------------- .../eip/message/channel/module-info.java | 27 ----------------- .../eip/publish/subscribe/module-info.java | 27 ----------------- .../event/aggregator/module-info.java | 26 ----------------- .../event/asynchronous/module-info.java | 26 ----------------- .../iluwatar/execute/around/module-info.java | 26 ----------------- .../java/com/iluwatar/facade/module-info.java | 26 ----------------- .../com/iluwatar/factorykit/module-info.java | 26 ----------------- .../iluwatar/factory/method/module-info.java | 26 ----------------- .../iluwatar/featuretoggle/module-info.java | 26 ----------------- 27 files changed, 707 deletions(-) delete mode 100644 abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java delete mode 100644 abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java delete mode 100644 acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java delete mode 100644 business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java delete mode 100644 callback/src/main/java/com/iluwatar/callback/module-info.java delete mode 100644 chain/src/main/java/com/iluwatar/chain/module-info.java delete mode 100644 collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java delete mode 100644 command/src/main/java/com/iluwatar/command/module-info.java delete mode 100644 composite/src/main/java/com/iluwatar/composite/module-info.java delete mode 100644 converter/src/main/java/com/iluwatar/converter/module-info.java delete mode 100644 dao/src/main/java/com/iluwatar/dao/module-info.java delete mode 100644 data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java delete mode 100644 data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java delete mode 100644 decorator/src/main/java/com/iluwatar/decorator/module-info.java delete mode 100644 delegation/src/main/java/com/iluwatar/delegation/module-info.java delete mode 100644 dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java delete mode 100644 double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java delete mode 100644 double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java delete mode 100644 eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java delete mode 100644 eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java delete mode 100644 event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java delete mode 100644 event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java delete mode 100644 execute-around/src/main/java/com/iluwatar/execute/around/module-info.java delete mode 100644 facade/src/main/java/com/iluwatar/facade/module-info.java delete mode 100644 factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java delete mode 100644 factory-method/src/main/java/com/iluwatar/factory/method/module-info.java delete mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java deleted file mode 100644 index 9121f0049..000000000 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.abstractdocument { - requires org.slf4j; -} \ No newline at end of file diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java deleted file mode 100644 index f075aadc0..000000000 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.abstractfactory { - requires org.slf4j; -} \ No newline at end of file diff --git a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java deleted file mode 100644 index 78de5a786..000000000 --- a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.acyclicvisitor { - requires org.slf4j; -} \ No newline at end of file diff --git a/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java b/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java deleted file mode 100644 index 8f331c848..000000000 --- a/business-delegate/src/main/java/com/iluwatar/business/delegate/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.business.delegate { - requires org.slf4j; -} \ No newline at end of file diff --git a/callback/src/main/java/com/iluwatar/callback/module-info.java b/callback/src/main/java/com/iluwatar/callback/module-info.java deleted file mode 100644 index 21a7a732b..000000000 --- a/callback/src/main/java/com/iluwatar/callback/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.callback { - requires org.slf4j; -} \ No newline at end of file diff --git a/chain/src/main/java/com/iluwatar/chain/module-info.java b/chain/src/main/java/com/iluwatar/chain/module-info.java deleted file mode 100644 index 4f11ab327..000000000 --- a/chain/src/main/java/com/iluwatar/chain/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.chain { - requires org.slf4j; -} \ No newline at end of file diff --git a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java b/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java deleted file mode 100644 index f8bd30a68..000000000 --- a/collection-pipeline/src/main/java/com/iluwatar/collectionpipeline/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.collectionpipeline { - requires org.slf4j; -} \ No newline at end of file diff --git a/command/src/main/java/com/iluwatar/command/module-info.java b/command/src/main/java/com/iluwatar/command/module-info.java deleted file mode 100644 index 0e0c0b31f..000000000 --- a/command/src/main/java/com/iluwatar/command/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.command { - requires org.slf4j; -} \ No newline at end of file diff --git a/composite/src/main/java/com/iluwatar/composite/module-info.java b/composite/src/main/java/com/iluwatar/composite/module-info.java deleted file mode 100644 index d75a7b8f8..000000000 --- a/composite/src/main/java/com/iluwatar/composite/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.composite { - requires org.slf4j; -} \ No newline at end of file diff --git a/converter/src/main/java/com/iluwatar/converter/module-info.java b/converter/src/main/java/com/iluwatar/converter/module-info.java deleted file mode 100644 index d83a43c6b..000000000 --- a/converter/src/main/java/com/iluwatar/converter/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.converter { - requires org.slf4j; -} \ No newline at end of file diff --git a/dao/src/main/java/com/iluwatar/dao/module-info.java b/dao/src/main/java/com/iluwatar/dao/module-info.java deleted file mode 100644 index 08e4f662e..000000000 --- a/dao/src/main/java/com/iluwatar/dao/module-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.dao { - requires org.slf4j; - requires java.sql; - requires h2; - requires java.naming; -} \ No newline at end of file diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java b/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java deleted file mode 100644 index 7abd78826..000000000 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.datamapper { - requires org.slf4j; -} \ No newline at end of file diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java deleted file mode 100644 index 25685d4d0..000000000 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.datatransfer { - requires org.slf4j; -} \ No newline at end of file diff --git a/decorator/src/main/java/com/iluwatar/decorator/module-info.java b/decorator/src/main/java/com/iluwatar/decorator/module-info.java deleted file mode 100644 index 50d17f022..000000000 --- a/decorator/src/main/java/com/iluwatar/decorator/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.decorator { - requires org.slf4j; -} \ No newline at end of file diff --git a/delegation/src/main/java/com/iluwatar/delegation/module-info.java b/delegation/src/main/java/com/iluwatar/delegation/module-info.java deleted file mode 100644 index 156477cde..000000000 --- a/delegation/src/main/java/com/iluwatar/delegation/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.delegation { - requires org.slf4j; -} \ No newline at end of file diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java deleted file mode 100644 index bf47d2cd7..000000000 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.dirtyflag { - requires org.slf4j; -} \ No newline at end of file diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java deleted file mode 100644 index 4f4216ea7..000000000 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.doublecheckedlocking { - requires org.slf4j; -} \ No newline at end of file diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java deleted file mode 100644 index b1bc2e824..000000000 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.doubledispatch { - requires org.slf4j; -} \ No newline at end of file diff --git a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java b/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java deleted file mode 100644 index b904ee1c8..000000000 --- a/eip-message-channel/src/main/java/com/iluwatar/eip/message/channel/module-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.eipmessagechannel { - requires org.slf4j; - requires camel.core; -} \ No newline at end of file diff --git a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java b/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java deleted file mode 100644 index 50eab8360..000000000 --- a/eip-publish-subscribe/src/main/java/com/iluwatar/eip/publish/subscribe/module-info.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.eippublishsubscribe { - requires org.slf4j; - requires camel.core; -} \ No newline at end of file diff --git a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java b/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java deleted file mode 100644 index 93ebd3173..000000000 --- a/event-aggregator/src/main/java/com/iluwatar/event/aggregator/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.eventaggregator { - requires org.slf4j; -} \ No newline at end of file diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java deleted file mode 100644 index aa9b6c29d..000000000 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.eventasynchronous { - requires org.slf4j; -} \ No newline at end of file diff --git a/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java b/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java deleted file mode 100644 index a3e179094..000000000 --- a/execute-around/src/main/java/com/iluwatar/execute/around/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.executearound { - requires org.slf4j; -} \ No newline at end of file diff --git a/facade/src/main/java/com/iluwatar/facade/module-info.java b/facade/src/main/java/com/iluwatar/facade/module-info.java deleted file mode 100644 index 966758790..000000000 --- a/facade/src/main/java/com/iluwatar/facade/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.facade { - requires org.slf4j; -} \ No newline at end of file diff --git a/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java b/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java deleted file mode 100644 index 9440571c4..000000000 --- a/factory-kit/src/main/java/com/iluwatar/factorykit/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.factorykit { - requires org.slf4j; -} \ No newline at end of file diff --git a/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java b/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java deleted file mode 100644 index 4ea385c8b..000000000 --- a/factory-method/src/main/java/com/iluwatar/factory/method/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.factorymethod { - requires org.slf4j; -} \ No newline at end of file diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java deleted file mode 100644 index 55c2d7714..000000000 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/module-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.featuretoggle { - requires org.slf4j; -} \ No newline at end of file From b3bfd43bffdbb02cc9b990c9616ebf632c0896dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 1 Aug 2020 15:54:46 +0300 Subject: [PATCH 168/285] #590 update Acyclic Visitor class diagram --- acyclic-visitor/etc/Acyclic Visitor.ucls | 115 ----------------------- acyclic-visitor/etc/acyclic-visitor.png | Bin 26645 -> 49064 bytes 2 files changed, 115 deletions(-) delete mode 100644 acyclic-visitor/etc/Acyclic Visitor.ucls diff --git a/acyclic-visitor/etc/Acyclic Visitor.ucls b/acyclic-visitor/etc/Acyclic Visitor.ucls deleted file mode 100644 index 03b6c77dd..000000000 --- a/acyclic-visitor/etc/Acyclic Visitor.ucls +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/acyclic-visitor/etc/acyclic-visitor.png b/acyclic-visitor/etc/acyclic-visitor.png index 636532c4d5d6443c94173fec7b0782eb8b661fe9..7b4df13d80f8c0d1be8ca32cbc39594bbd9ec7d4 100644 GIT binary patch literal 49064 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 J8O zPgQ$w)!R~0oVbNA9ZJ>t17J>2&))K*+-HqWmoG498T1_7&c%9n+8iEi?VY&-p4UYe z2a0ysoaUed0UvS@a}(D94ny4LZ?36`pTj;M&**%--m@tilVjsKoC}S5=wUI_`%G{@ z;rYc~pF0(vs=n-r$~xVXmuI;g(UxQQ>-abUkbcb(kcsi4*=~f<$voMgJG)jO4%)+) z7s90YcFdyeS0#>oE?3Z^_sUHi{29irC&`*$?fWJWkoi+A1pkpc*zQQ6n7c6r$*zd5!xV zet+T)6c{t8i~(Q||C`b^NVTyzD3rzei5Jk;L#04N^4KwN{!cSt4*i7y#u9K{v&ITP7{`kBJm1G zpNiuEd&->iO<$j$wvNZh!`xv8dPekKXn5}l|1qG3o;iJYug-#=`1=o)+V69N(6Kf& zVE#jw7zcf-=<;?T{E#ab%q`vqGLNT385AMlT&gsWMXAj^A+0~5Iy8+$%i>W4gB16G zxq}423Lq8SfF50ii2L0iUDcfV1|F+&8lmO$-NwYiKe<+XMX-6aa}4^YP-%Njgm_Pj zvFsg&U-oK*T1(l`7V_kqs!oqEpYhUL=Mva2&6wfu37w3*CN`wl?5a_!{3fWS-y$YZ zPFq4C-#R-*L_{txE=u5XyDqVxvQ5{jUCrYBdQ1opVT5CbI4USaaeNOA3N#$J?BTbj znrN?E{p8egOZF1pSKk!+?BaN|MAS5Nm3-A9jCvvo5$G~fQrR6JAQ1WTQrO%Nx;Zkq z0Y3C}a3~bMlp&M}l-bbp&+n|2D)}uYN>6q#2gs6T*+Y`ZUc&jdnI^JwfrFj{_ZMVh z3HyD)TsQ)7pjbnI-0EHH@nbCJ(H03zJIV-w2U7Y{ZBj(wGfS-OKHnTo*YZ z=qEVU>iRGIOB$p^x}`xvQd(NNyQI6jySrl(ceZuTdG7t5kAGQvt(kY;j^A)qJJXj4 z1+3l9Vh2MMnyzKB%SP4-rmP0R40iJp1d`sFX_Vc<4}owOG!pAP#XWDDa9HrPD5 zK2i=tJ41DhlRb-Fc?E_NXxs~W_sYqp(NTFaK<ip=+_CpwYS!ACx{ zpKC4@ea3qzG(kX5_y9cejTfw@$s&`Ulz^w&^{~e7UI7hZLS0F%LcK?P8*e?Bo&p~$ z5CconKQ~#8(b4S1in@!m*qBvNuxQ$w{|G%8yaht@P)R!kHz9o*nRfE9rPgQh$Wk-Y|9VQ?IfqkE{baIX=-qrxa>@eU3P0+y5vR^znK)`52-rvEfY6`;%%X5N%=^*L0X?>2QT;^S zaSt~MKIS>2SRc8#V6)XiwA=wQ()W9SLR`XIta~P$B5H`;fyJV58ntiDkY`CAxU~QX zBsVm$`J+^BM?$l;oBeIfgNIraT($NFn$^;ro2Yi52=`!X0yKoJd0!$f?!4<%w1lT3%YXx>a$vAO_ z;DeqobaN}c1NAWWg+Q{wq2Ty5zYLI+xZ+nsEW#|RkEQ-ZPA%rG^y^cQg2tapT(4YN zrt3^6i`N#P5OdCJq+hdaomp_6Ws_95fVYf3AWXjxBl}Oo?b{DxgO{|6GT%9F)vF4# zJE9y_?6@m!M8V6nBIYsiAuj+}!3M0-vmr^?>kYRBq!82%SKKyV)AFfj0R zNI$S)xsXvq{PGTPMtd+9njn26k~laYH`{xF6hw5iw3C%cgd2LF1~pP|UYZ%DHW>ib z09!af5nB3*=s~k^+!!c$|Av?je($G;Ybcn+vHd<&@k?{TfrnnF1IANs3~)q!YpTj! z?JUW4SJ(fDx~b8>JW295N>>dWkeqCG)=#~2#bf@WZ|>W>tTiE7_6V)?2F|P*0$%BqTK6D6pRlgq3G|DAu_6O!vK6d;(Cxl>h#S*7dex zxBVwko_XNR(3MG1ivboimy%+8@bD{d4d!K@RKjp{p&ECjjuox@w07I>YUvqGp`L#pO&1*zv(FnV;bL!r153&vvK0o(sMAM z$lw)_5|~gYQopHwCQ`0=t2q7j4ijCTA6k?OR(_3nbkG>v?d>8P?i~0srDHGDu#>Lr)`Ztk8w#aB+4qnJNKVo zWid!|{Q4lw;9vsvYL+?pcEj1|`SY8@v+dGF8KlL-bR3oID9HrB&dQP!z=by~R)IeN zXe0zO3Hww?SXgA+@PU}~xe^y&1}Tx4nUb0@C0E@?rkZ#7X&Eit!gT~@b6B!Q_3ny*&sSSi+#WPe&W5aFJNK)k1oYOmH`tY6{^DVEdKa`D-yt zL+H7t*Pz#gI$rrPq<|W)7`40$n%@(ni@`=YQU;=bCJ~~yqydhG|EoNUo-#J*dUZTT znpptk_o5p2i)}#58ko3DD=@Ap%h0mS)QRr<0nV zSf(8buO2Zr1N|X;O7{9Og1$s^1KphZ75BBEybM7W&~HC4fri2Rdbw{YM$iWcSey@- zbl3QBWlFv~;ad;~u9IPSI2kQ+?u;8yZOnKhh64!fv6?hB~#@Bh%FtR8zY6dR z1iAPifoZP>d70s~yZ~jy?VVW2vp!@1X5)EfYi;F~w>Y5RH56X`ByDnLGO<0XK$RE> z5k;yL(`BkQ)f2Hhvk3ZL9gi%hE!&N)t;%_G3TP}7hDPSJ-|1uqRbW7}fdV%~j-K}& z-08c)z%iRs;OhM_vG?+HL?_e|$x{K0t4!ll*ZiArC#Ve#3nSvPBSyjAT52t8;>3G| z5rz1@P)<+{(M=vWI7RM`&wITvO$gNH(GMOTEnoTf1Kmlud&F(#-v3BR+t*RY3xp?M zzI;hd83Tjg8xR|qhhCvXq_)`wtoAJ(MS$RX(nmaMho9sS1*Dt;er*BQY~C{~DXBUN z%Ic-Glx|Vst@3-=SIp@_Yrr{*y0#Uf))g954RoiW+)!C4@jRMxwne#Stq@pyT^*VK zC`?@xv?fwz6fRzd;QA{sAfxL;FD|^iyaw*j0H8+><=I*pE#fNbez}7c#tl*;NqCNhig9BC zecOHZGK9lu!Ba(H=19O-S@bMQA(g($3vQW6?T7}KIQoSaYI4y*XA*Jfn6d~FODJ>@ zJJ`F(T_MqR`YQGLJw39wh<6I~ zVLws^Kl1wXBWOJywDZAp0bliB2su3B5>t$LI_`Y`vRA5WXt-qRn7kyx|<&) zbGrK`ueJ;&_VVmBB#Qn(v?Tf0>QPQgJRe5&4njRLaucFC%@fYWJ)8qkjlL%~RTYm(+DuAU-zhRc*rkFQZ}BOuaAXGDW_9v3B`h?J=+Ix>WjxO1U z{|A@CT}U=S3QB$qg)_CbpGs$lBD|4zI1g5N{J5y;R*UcFMXF*VGnet5hzIgpmWnMo2zVnt*X@941UOt!3 zZI9L#PEmLwQ&_17hSUw0S|>pI4UI0o4C2ZdlEmX;zsIC(^ZcvA6X_Kn8UyZg3r zefMl4N??Pn3t8V-7!}4%p7yxUVT0}!I<*So3#|o|_b7YY6TXqOTSMaj=jI&Rrp*IqCU0qjn&i>^I(*y&3 z1i(E3C8Q$imfFh1h3U%nXZ(mQZBXfsQj;ko7TY}y{;9xGlf79@ zSyXfdzz(2egq0N@jIH46S?A$Zz{;RAJON}B0jQ6! zveTZFo80N;Xt}&P6`rG%a!gy;64a<3CSHO&%?554y4UZ7{zEO^}4hZXHoG1g0!A{p@L;js zcyj+N;+*dUj$A7#@d5q8$lQ@|#MZF30=w;OO`U6^y~&3~%^L|qgXB`fHPEx*uJx#&DVHZmy14 z<7N}%!3+!b|0hgKQxo<|PizM0Oc2xSiUj$5+>G)@-2l*VFH&W>G$ICrUka21*i&F~ z<51I}2XA-x#)0!iZuqYey>#T#k1MJfrJ&dg#;5J0ZEpl8+s;AF1y5?< zp7V9Hb>zi^>SKV3sRZ;lYox=qQ`Gd>ETa zor+$f;brLfntq0pQVlTJmV)+$v^4S`YFXjdfii!9TR!^yH*kwR-)AD{h#P7N2MU@mI}s+=#|8r@N? zmg1%^$j0_78u@0Ku{fN1jkoC5x#EV4{n~A?aS?!G*4r2)2N*4Vn#llo&DjevDA7el zP(@h*46gJw>lBn=|K75yiM4E%B0B&F0N5`wP-rCPsrnnM$Ga%6oS&JC2(WT+tb&F# z0N+-BnWYLwomM*a+Lu9h)A3Jt7L3SkR~?Z&X=AUBDNsZHe*mu>_Wy=@0dUHz7MpSm z(6#7cMEpTH30K?-FtG=Ny8^?Ls^xUl0ATFqS>d3_L9g}v&!Cy=@?>|Cw^apq(!sc- z73i-u!hgJfS#NeF=X!(tX@7pN_qPK2xn;Kb4cOqin;Ow18WDknQM1vUS%XAtLdMh#73!Ssgg5Wk`!z6VWYcv)2gJlrMclwhMauXQblzv#RcB5Q=Ii4^I zd&U0A{)(NiJ^3DirF?b_;@FZ^(M>1;%Li8vL@B!$-2DUvjrYBp71&EUh|TMpY8rYJ zPVOWBsP+-NHM=3)yVaB2uDT92QvlUetZOUwJV zdmQzL=@UnY*p$=e%|A1{3?5w?TTCG8jVLWRTvyn8rAdSS=SpoHsXVd?>88_i6Y6QB zC=aqx7D-zr?eCywgpBByYw>y|Z}#h&y@w;Ui^+5vpBIv>ZQoR_L0i5el0k;SO;H3r zuDwg5G8@>gasT($I_Ivj9Lwv~SQ2-4YA~yj5UeR z#H4e!r>XN^CQkgt{S|R=q*pihgmG{-p;uI~3*?<}H$Q1%8*8 z0P=XB-EKX@H*9s3W!;o$?WI%4oY^kzq`-8}_weu^zy+JD$z*rAiV7l#9nI9i#I3wO z)SCn7_;vPHy=?}{v8>8R0x#|D#H>GVuCA1VM))c|i^b-KVuN4>eclJ6C!>xgTUp$W z`m|MI(V=W+_X-1NY(d@>x z-W@vSK{6($(~hvE;kz8_dZ+zf6ylpw?{_AnYaL245pCD|bpft|5FZ0AZIucOlg(al z3`-sg%B{qcpBO~-_3!+Gy`TrQG*pS))nRFZK_#|URtue5a=$ibYyGFt zd-nReI`Ao~>}3xYTQWJUS_>X%61+OL0(Q-81~GkpeE`m|QZfIMx>)dCIJIKTj3>ZX z6n1q*{rK}kGrS3CNk{iW!hRooUrK+jyEkEpJemwD!}e%+cQbmU@cAV>(KgpKeP}&v zj=)#w53-01mBn2*U6PI>H;>;hXmJL5@_dHYU8npk-wB$(E{6j%F!-P z1G>}0L&S#I! z*lo6dhLVdLj}%#06I=`k@_Pwd<*ISa3>NwO2_Iz1i%+~|!=l0AHJhHIED0jI_3CC8 zHPF>X7OZn*3s)_XAfJe;(*ACw_*~P`r6{|xN^!i8+HNoVS!Wuf92$?(Xz2Ejfs*={ zGlxf~`3uWB3(LHQUX8STg{Ly@3HKb*nE8tqS>k?tsdyHSUZ^p2?KY-|!ZyP{X6D+* z2)Fkm@^{YXY1vv%qtGLgLgfg}*vmt6qTB~y2mOOvb4w2FfjY6bc@SSPWZa zi~{Rgrw|l}N|9?7tTbO`lGSCb|M|g5>}&HV`iG1D((0wQkMdPmQh-+ukmW@rczT{a zc@n!dnwuBH?(oS2&fu1g)u+m6e`tUr5{G z6VztIbms$C<1wJOx`zUahyCMhpY;a5Zi6u!xhoJ+1m3a)POjSVh?zj-r!aN_QFmKfa|DtMIt{VEgzcthC>fb z7pcIwD|AQ7AvPMfTDK$Bc%&PkCBHP30=+|$FN*Wq=~S5AKQAZQ?tY>Mqozk|=BCHq z$i-X3g&-Y}Di}QK=O-9GQCtb`QaRkpC%|XPlCQ1eDBW9K1+Z^TVA}5dvZ`1`(`mqD zce=1KCJZT&ZI4ItQEegX@J9M)4NePYM$v=E&C_;m?rl92;bj+FA# zWjhZXI87q0d{D&E&>A)BgNn-cUYp8W-Q z+VxJj9h-~+(`C6kRo2Drt1?~PMM%ojiW0Y1M}#?fGEIoG+8Xh&i`|H zqm+i%kaOP8JQPZDF5`;po_v||`9%5vZZnizhLJQZIo|eM)dv0m7aYR6uY*BB>Ry6K zr5`3MU+a5L= zC8aa~t*f(_wY)l~C*Wiy=f(TKeK_+(x%_TIk%i^qo-PyNp>%7nc`%4-&_^ilH&cx* zn>$%b8=aGz4Q@dy6#>b~8cR}N%(C*mpLyJ2T-+JRc*mnyVTI`0H1c*Ns$zOfSrrz`-RWJR zYT6xm>_5h3F)USBW#C_kisYzs%I*)5F{S`O13|RUx*FN?Oh>00A{#6wY6MTK9(qN$ zn})4n<>Y$tuM`{D7BNSwu=2gV2o?O^kf;$cr>TXXh>}Y(=MZV>qB>FH<=|= zbvk^{!^gq@ube8$a@thLXX^`SNS#aR3X4WEOTSQ{Rbp_tI)8)l1dWa^sFC6Qn|Mw( z&Du-ONR7HHRi@&@WoK}(WMrO&^W%kZnGGtXG-~RCF2~XX$HzEWnw1}`()2LV!xl@* zi+#-cKevY$PcOB(l9+c6;^HbdechWy#>9H{G4YCTgvyL^>ax=zAdRNxly!< zYuBuv!3RkrDWqPtnE3_9+7ulQxHz=HJ8zlFZmh`F@DAP9uxolPs9-nz!v&UbV|o?O zS*~h*H?zT`8U)9yK!tQ}3zB@8VAN#jR4Hl>kU~!2t}Yh(+Q<VvAd%!nr=`DMN9i1RTYHYOoiH+RLnL8x3ut+<&gy#UkqWyD$%j zuPcvGzDQs zaDpn2_$;Cq;=1F>r*!Y^3o_@suCvEibbazJLd@R;P$~t~;j#n*-57(yp`tqcBqPYb4 z{psl|w^vLi@6vtRbVKEjF5w%t)_rd5Htn7}C{^xQ!y z*+#$W>QPhHrjjh(Pfb!2{<~xn9?iEO{}7puwQlhtx&gJvX9eS;M#s~uc0xx{|9~mg z>N4_50ajyK(MY=|d?8nsX(B6#m{iRPn#5SND%OVS#_A*YudleOY|UE+OA>$?I={LQ z*3`6JaG|g{LMI=-4+p0xm!nh$w51q}iGt2p#D-cAVa)e6;KfT<*T*MrJAB{y2AtqZ zlO_;h(ZS*^)VoGsb!#7e!GcA&I~RDNUKUk-m?}2bg$I~|-`G_zpnD|KQV(e1$RcT> z`se#~lf}&e^Pf3wt0HKO8t>z-NvV10S~wmX_6&Z;oGmxMaJy5pC69l6cBUme{xR9A zl>LX#@6YR{w0gFe-zKOTOT7MEqAu;W;&RG_*Moj}X@o#Yf*|_MZEb zimlvo4owsrJlCubx;&jq0;#aUsml|S?TMolDRy%5P3T@cEp4`xg2#Op??)SyTqO#k zSmnOJ!WVwmGU(Wgq%nF%h?Jz4!%*Ja(2$J>{JM-F`3#BMS=Kd>22r357|q3})!-@w zKC;T^5)sqMaha1CmTZJzbPvqc{-S!y;x=RuzKv_nku>TVoo|x*l&KLzMf1bcAGT0p zFL@l%{MYi|9%4$Ial8v)c_K-a)Paa!5E>>~++1eL82;Uf%h|8E1ij zZ3SAOALO4klgUsk6Z1^@C|$eG_blWun=J0gYj;!Ayw%oNP&+U)c|RS)(p4!O_6oS< z0DazNOJOvno*7<`7U-hW^1I=Ge|C4xO+6-^X5A+c7lCMJdj~k!nPbBen`BtAna9qsc2rEJ~fsFzv|fLWB#*ONRcHm)Uer4qcXNc&k}37NRWdW^B*zB6!T(wDvdq}mtG*A7}BhIrAFV11H!U*#u^oU9PY{R-J5(5nrFi@>0*Q zk6X{xtFYTV#aG@KYASpsK){NKmL*LC4=aGZ@$aA)T z*CDrNnq;{usscxOA(jnuBs(??_xi?h4cs4>psaoBGzKihk8Yqo0b-g%9W_!Bf=Coi zbaT$WrYiwywU}}^xRcOhBr7^C^&Mq#?tZ$s73IQC?QnA{yW{BA;mRCh@Q+-%%;|Ve zWl1l+WP#)qTLg1t4cLLxR=?8a0!pOeM#1f$V`0dlsp{}5=rDE_Yqxbd`Mj>Bbzt$m zu9xdAx9(&KeaGHtj`9x3#&sh?FYG@75S0jF$zV#A+Gi$pYi#x|`Qy`Ndq8PFF4}h}qVM%aN?6MG5yJBeBHc*X5PM^3+u?p^gv# ze^%yNQ*aj7gmjO(X1jTiF#zfp@RHi;qKKY6F0M-2Q(60CEw@97zMfp}KFHJSzj5fw zVYnCrUUxI??OtN#<=!-hp_ztX8YyXcx#3r9cMgzP1fixBDWAQur#c5K8Z1~X0djC4 zRFrZbs(MG{ulyvfIH?=-U}q_M%}6>JR#J)iCAxg9wHpw;2*%XcA<5G?$!G`B&^OmK zEg%Y#2~RVQd*jWz5qTXjBmy7OMRwDP8kRSb0hY@meMTiu)h3{fE(E7NqDFqo~$_ncY<0sUxtAZFCpuy*m7)SMQ!bPu6rh*;EEdK4&25 z2%16k-ntzseiDj_iOhKGy}UiGsrEVtn_gmIK_H*cbJqAmJ5#Tx+SZ((*V(H)I=V12 zQvTU9R+D^k-JV2ViEq&_eL6?J`2VeHpdJ5-FLrL+YRm%y0rJkSV7{@lMT39cX}d8K zJ)^_1n;S&Z5*IE~7pR~HPTP}Je8DJ{4|8f;c@n%w4yPZQt`t5VZtw?C6x6eSq`M?| zakcjZv(zIlxk60hc(sSaGQ=-uKTTBmwr^Q#Sk5fBAd&^#y_dPK6Y=SI-5ZaE$KHUJ zB*2Bx3+*}pscW~$iDdt7Bre8~P zk5rGZF_%AkqX}Qt%U$E9L76*>tXWTZ4st;w8n$wr=EU)Jku=fFxlE&s}Amg#v)#(lrK+7Y-t145V zMf#XbW7~Ky0|2j37n=vtDh~p*5UCNB5|PhvE|(y?Y{oSJ}RedLSz4w z*1QufEEs~xE;;szd_0ZUAjT8ysp7RZ5Yq=N8LuJB>Bp804;Rzi9JCP?e&u=(AnCSd z>s_B?k(iuIP+uMDk%^kbc!g9`<-isQjCerqzQ+Ue+=6r2A3>J{JT>MZQ{Nj8J$u6S z@}-8p{)$m4xV~bj*Z`lT*SMu^?|Cqf%N4QtURsIT2u+$lW^ae_nzjHxNV(HO@l#EN z|7Hv<>LT-h%l(PBNxj^kl~%iOhdhn7bMyR7Uhx;OVv#a;;a|@WlR{A?Z(5aFtXFab z5y{jTthBh1Lz!EztOs+~HLXu5yMZQsQj&yS@nZ*=*v?g}pyap*U%rn+H&ZCCItjq(|t07#ZP_9d8(uMC2C2WTgN-Kn-y<1T_s zA@jit9jy_jE$<6eR7*Zdmw(Ab-FLcN>ll?)+6WkHImbdmA$YjnH3QtsRp>aj+DkB% zCW>VFvJf*pWiLCQ2YNE*3880nelp@e|bALnSU+!aPZ7XC;qlfhiRq1%0mO;q({HjP={Dr1}ARR)HFX(WOgdV9U=)LLkLOI>ec%w}e9u45j6jki)rE9l?4s#lk#@fC_hn+CUI z`F3UNTM`KdFfzVxkD0C`P^))Awxol}9W-y(Rf?HZ8qcpfsDmd0mxk=$O`4EV1Zksljnp$ff;ZhU;y%?oz>N3aCZ<(H{Xjo z)7|*&jPA08;m@Vk@-p=<1n`>Kr?LesXJ==I;{_A}A10Xr;GC-V;e*Re<&t$DprEAH z?`31+RYe-J7)qsRaBmU0oU5<|pkXAX_>G=|3t>a#hiXbIZsB6?nJ>u+SbXe_k1?;Pui5r)^jalPEwVMd|Xh`R)(T8tdk z@>kAL*@0XxPhWzf5CESIMfmoTbc+Iiusb>hTs1qB7at!ONDfH7f2gO)8fXHtoCFsuk(V+*Iq&7-u=Au#Q+UCOJG2i+(C->tFyL|3bnQrsr)C~ zL_UN|a1*s&5o5{Sy1HFHtTW5uyyvP_VY20tyr!)+{2iebjpssd{A6HdQx%(&yHO0f zHdAFphGS^hZp@VBOjIH^!v)vKRIi2m|D+E~&OIixy?>y5zanw+o6P9>8lhW^EuH*n z1FduWjuW_v=^M8rGqm^wh?_Af;2$pF4C|fBkAPvD_wS3GSmA|rp)eMD3`<*n)@gk- zU1LwEI(>fNvD!z}HVEu?;;Yh#x`zPkyGEvBSzt-@6MAw|N=iz=QyP-$hQ@^~dZJ%LuEW;~f6{l&MC#|mX1D9a2L z$G#Tp*IEyPSUw-5S1q$(iCZcF3*e5G+fBIIeuJW~ED{l%V#BR0EZCNpRh%6}RYuzoJYS;tG z)=9N*(;Z?5!xS1k15I&V#bi*%(K)6nX-@TEurgOF=WBz0cQURW^bD$>h-u62zjTVSP=6o_@ zu#K3#>DnnbUp`laSmR)wZa9D%7AEO>p-1$w8yIVhjq$?F`ua8y>`s-HVn*@@f{U3& zw}`vjQoC=m&-!>#jg^tLxeWc#h>GjY@-_?)2CISJ0+!5rbi~r>1pX!M`Ye5q#l&{L3U>$Yu_MAaY11n0HP1>%5!>mP=D3LmF8$t%Zy7yVIZd55KcAo5)#?1HQe(Mlt!$(^$lJ-Z z(;UbzgoKO$01Vyo%8;F{=}HcA;F%nsj0I)23=8P@K5Z$r0o@Q65(~NU@#62AS4&FP zWzxjPiN1qci9a@d>qp=@hh59-&l$agx7pJW+W=t9p$+O~+xQC_uUIKDD}_}SJrN{m z>=r(=acHG^j}YUlfTD_MB3C89MYisx*TOe!`b$t30iC0FfKz~xz$SnRpD#u&#^VTb zAf?92KlC$Q!2X5Fb8}|t;wc#{;7xT$9?H5qWp-izidU#YQYb*8F%s?Zkhgg3s?B=8 z=jV=&j7&Y&RHYqbP+LL@{-|DR>}|0XoV_Jf)Jr2y>k5*hAPyRID0-OPUUN8-eN#dl zsYOk%`->!*Ri7wSF|^oh>1=uj@#R{E1b|AwLXL82PH}8A=BTH zC1T@Qd92^a$e_)={L^t!&8vi6Teh0jCq8}2tj4Lf?IFx&P6aNZURoXoS9JOS8}H~y zFRzbUMZhsw=U{yVQh?Ff=z@boIzRkDy4IiBT!Z)7dnWh};jle2TcJ0`NBQ+dt&=k9 zALFdI6b#C9z@3nd-qc?RxwR&W%;gmIL4f>0=ArTQM5QaRRv?KM3pATm+OivE)H7HD z#=~kYXru&B&I=iZA`nMgk|!Yz1Q9I)m`o%2njX`vIi(;Q%E9{$- zH^D@pEAF5JWRHA{XJx?^GtrDINR~CP!Sax!3qbG5N1cO%1GYmy^f@}zf|7ctXa0Td zy#LGd!^3j_c;3d9xUe&dzQ>Ga=-HuHLxVEYIi5#j6C22I%RV)r3Zb{Y0E*@Lo~nJN z2LqPxpz+N9XZR&ARkDdML?6(YZ8oBo*T+k>n_@tbVmnfVq-(^QEWUHH+vpW>eUL_n3v#N})}$2==s}dS4cxhJ(GdpNwgC6|<;PU+0H%6; zj1n1(pN;gd4vst{CM4g1u0=Gcp1)c9}J`V3%b;nX&=>tk%8*S2i-}%k*q=OZ|~Sy{x6BBRF%% zh0o>2QafniF%H#0khK{fS-czN1QzKau)J0rY;7a#dJ)q%1e@3WMOLkw`IrpH&1&ob9)4kq#`y)dL$F3pE0-GCn@M4AI*(znNFSj&S*d=_n4Od z>StqWstzckJD%x_UnNuhWdRVR2#&~OOG}A_XJGb!zk2*uR1U1IyyD zRBAWT>%)lcx?vIuWv(o?_Jn{YXT~GpyC5c z|D{^t@YG^oL8TY;D4cALM8hMs(yOiWHAFKBM$l`jR9Ni}XXau&Leb!F*&Ht19Nw5y z9U8uGwfF`;lYm;xL>?Hhk&9uWZHKZ+@+{;!E0*`~YgEe3nrW-PlL=DC9lT;mhNcdA z=^%$hWm=a6&eX)os<#4w+`cx{ zG--r9Tq52w))fWXCZLl5^tmqDxeM7SuwS=ir|i`Gt=MQfc{KtiPZ6=j3 zJtvLY+SYb-jaW251na655a&{BAdW~NEY=UqX4jAkjlz_0JY2L0`1*1w>Lyq2(7p;b z0S+T5jisgKa6I_ra&{Tq#p`SSS^;N4?r$L>KhLP!1@dzkY=Z;~}q>QV@uU=59beu)m!31^-mn{auRdy7n|@PB`~ zoE#b&+Ah)3);0$@biWL62)qn(U|?a1*i#HaUPbmqTVa4-2rzMdku@==vesrG1e+L+ z0TY;zcGPbChX{kJ)K|xgJ>RKn7j2);Ga-Jig$V)#yq=hs!CWg(k4ej%7n{crXRwR% zAyH!OQ^U!nJahI$>DREidH{_8ajR*lap%y^=z5xeAH`|dtv?$)NWe>^lnK4Q&bavU z`46YUL6*USx}U_lOqdLsL1Rvwrip(&>zP18bhWQUlPLZDKkuw`w}-Q8owXsYi8nZu z_IT}@PF%C)O4DD`rfJ}^!h{HN`!J>Q2ol2fjg7(QsZz;k`3*6T@#FOl3{ThXS2%K& zV?z~NPTqvzx;WV3+<_e4Kf1pfvZd&Hl-++~EcYmp#PwJkv2h9?4nrQwRgc$au>Rn; z7Qlf(zIc5ZgV#YvPS~P8y{CF2S?3(w*N+cg(+_|pz%*}&E!}N_z3a}K{9T@9rehc( zek}(AS^kQ|H0sIvG&J=5TVFrZfBnQUyi+MkPrFAjotv%z|K#Jpqkup@`Y?hKZeOCH zGW^(^Ma;yEsK2BDleyTsb;7*dhWhWy{c!VT&bgfboIV`H&GG>7ljnSx6UOqFFX1IX zJH&1Cax<|6_6_O$`!WtTz1cJZfSCXyW8h}{_2%%Tu$S&@VxK~~!M^<^@?VaCq>$!Z zv^O^yT)gP-j5X*GR0$3utQCr;tk-<vqn(9rbEaUobcVZD?N`S`qx%`eZcvisvoQzl|{n1X)L0jIqT9-+e-VYxh`2 zXMTiy>im)NA91<^`H6GkEV`fRK6fC!ucMoxuMnZ0KZ1iHjsRr^IH2&Yz`pP{3y<;Bt5*h1 z?o|@`d(RJWz2W~Is*caL*7UHv)9^#z*rLObnSxIY@U#=`3|FMgL0o2%^GoE#yHm4VbZcQXnXeK0X zHyGgjG3Y>)-5fNYlg&&%emvkDDp^?Ol;9*J?BrB%vxaSux5D)0KcYL&%LP3djqs}X zWFgwnEVBYzv~>z<9}}vrf?BxJ`cRvx0@APa6fZjym8RWv`hhO!wOGi{c9=Sa?3Xig zFD(>~j|=bK!K{9udcu1f_`EiaxNF3KIxglo9QFF`;f~|6a$f#;lK~EM#(kGF=%^MC z)o0M2%Y*2408?g=R#At;ElwW6Wbd9M`Y8?|j?_r5_NQC4bs>bR3yQWxp|*-pixBLw z8!4y3vr%sdPg8$o@t)zkF$5>Md!Xso2?MeOJ6gz>@bKogo0Y1k#)sq=En^76PGyJ= zCSEDt^z0L^4qD{1$h@_7Og}{O&j}vLc?j?ch~QlpB=xQ^$+d4@7R6_hCEoeFCZy;V zV6ryoH4boZ`FV5qfnI$R;W*G4hN@uQ6r7TOFXn`KRW#ukX`$8FoG0tw9X(;UAp!x>C+N z_^wv?FV2<@i;l4Y>IL7#>HHDqaX(_%1h>?f@JXemvRTFZa^hk_Kfz>qL_E^Y<1ep= z2G$ml^y*96`YyhFIPO85Q`vLPDMkX1;j?`xA&alG z1I**ZjPEZ?M+E;<35Yzf2Q6M3*}-R*tLAB;KswKQV+ZqGMEZy0E6VP#Uov4eQcUWXFF~~ z6hzjvFgkVM$qGsh!$v88x}sTUBH>h=)QF5U%IJpke`@>gc&yv^@2f?bC8IJ6$rf4J zl&w&qL3l)-N@0BvL%VmUYvPa0C8JDeWF5`Dxbk}`<@9*<^{hrtJdj2x5^ZI`1cteXc@0_evSW?~o4hXT@zolf4BCo_$6_DstzUXH!N087h{IR;l(Q_hT_5hES{qi+4=H zg>Iy5qY!fKveRg4vI;e5S+LVsz~O>S4(?e{Nx)3xrMb3e1+wncMRC+E}e5 zjJ^T8P4?j1J^g#xcIl+fOdEYNvP?|-;I&S)Z|9EBN;yw*L7F7YCXpw~v+CimU#U4J zhwQZYDASh~sr`hCYcrf(nY*aws}z zir_tZH74I?N)IB30H|(z`yFaKco$us4L2a^=6<(Xw4|?i61AXP-B4H6;NFhorS)8I zAvsX!6hAcm=YEq;Igk{YJ3jAZke@iC*%fmwY8s!80H?0c-qTEIc%N~BX z=4+jX7nZcFC!qIUkEh8cUZ5`%j-HdpS8v7BYfv9K@KX_iM~quY`BR@!mM!N~Qh%OI z>Ai3Dmh*0KBYD6`aI;~e!!k?5_Q_w{DxRWA!L8TPH}@DHZruBrubeaFkS6$zNPy^B z=tCad(hwt=?%%`a(Q7&+@To2}*X;-Ue$n^d)PWcKz8`YmGZVjA20GkJ1)0jm!OzOt z6e1O)aT@*fQ7xRC!w)(-&S>W5{eAcxkzwaE-j83Q^4z|KBncMc44bt^k~T+AHmjjW z_SbN{T^4@`Fes2oUx+NbGVPyZWSsF0)kYRrZ7fm} zMG((@efI-&WT{Cve1YAs9rut&uBX&ybsDQ*F^XyLlYU*wgm7)b_O8MEKl9qska>2l zZ|^m8t)buJf&O!b1%~oF8nJS3i@TooMh8Mj#bv|1r_?0_(AL%P`JQ0zIBo0eeI6Xt2C<%ck@X3n-F0u0>8?f#I6&H!Wt){L zx7yj@m6RGFi07>Wzec$UaFNrw<|70t_dn|0gm4L@!S!beO|hHqN;}V*Ea`t6h|e;H zNZTO+fT7`*yPOM&Syr=Ms_^hBSRRH*=IhL_lk+npL3`#chFM< zU$reEA?cq&fxAj+=FiBD|4h!@rpaXop>xz=8^G)8 z54%}V1eDQ%InKM+8;8rPLm71+9m*${Ao3k*Z@;LUC>{mO2HB;-8ABtZYE7-rj+gS= zFcf=;QI;NX?9tzTaqPu|&IG&~%#H>{Ib2(^R5@#`fo**+^R04~$cWvLK(+T86?b~V zk98okQoH^*qM;)T1cY-Jig|!72gGim(%+xyXu!a1&XzxzR3lC2U`VcrmCIk?EhqxU zcmZqvmoI8Bct0hspE*2nBFjaeGS>lgG&GbNXrpKKjm6qRE?izujCJnEcz}jZpbTeB^4xGDzB(v3K@h?f#&{>@h5DXUy!dHyh%{+B?_B z{rqL9M|X|IKF~rmwXh(28xxC@q3azP`TDh_F`U&7y41B7z)Dk77TvN}cggYaw7;gS zNObpuS;HY?qkF|;4)7s|d01DbhLC^&xqVBp?`(nj&1>a?K-F{KCyzh)<$$FCvz6LR)y!cx`vDWeG`E+R z@nzCnm0&7>tTw8XAPAmp414YS^X)2_jon?L`hb_be9WeS|1gc9yQ`ECs%2yHG4un? zd1e|Y;_GlSmNBf84Bw^*cN0U^GQf8U2<|Wcupg8V_VLf>ES(<9z2>?WB%#F? zSo!wQAwvt(DjF~~n3Dd}g+nYDGRsAMB&7X}$zssmtfZ7LaNxtynHXko!~}_^{M-9+ zEbM!F%t# z?T4jsNnhy#Hp~})7CLGb=>QbUo@_J5<885h4-5?0%u&1aet*sqwnhbDVnegiCBXiR3MKuGTVgiC+8u#j!>%it&c^10*+`9+ zK)EoWLCV0-&T6f8Z?m=i7Y)Vy=pz?tM0uMmkzr@38r=@A85CCi{n5q@2?d zc{O(OWzP*ppFf?L7s)!pJkYe?JJRRAJy?wkM(gyX(N}qgp!*NqGHy-G$p^yfM zzckr)vXP{hdkFk{puV2c2tCJTI6Bp`qE0(rM+hmUVvUh<5x25|)zrth9v%&Mqwl?@ zG!IR|dYl-V%u`P)hOcaHJlprZ){hmVQOyemVHr_B7`E>%F*x7orxY=^ZaxlB_m<|y z5II98<)k0rNiZVu*|@8SKyG&5t6^T})2Ma&D0ib>uU)k=nx|w^%~V%PmBI05nT(AQ^SL1v}IppYnm#_Dh4b%{Y{oFw}|IxOFn{Fry z9hyki1GXw$Opk&+o!26s*LHf~Vp91&)uqVRyu3%&BGo<{St?E9+zPXe$CE>)b046f`iy@Une#rgNaVg<0tm-9v7(HVofP!M?x-HI-Qbj&IpcZX2*; zOi!P9+z>2-(b;I8uF3LMzWm39cyv`uf%nw~vdy^r1y>Z#SY0LRV_`@&f0(#9$X|a6 zcxTPFI;FF1-Y=EEhuoG|LDt)Se8K55Ee>ZIbx6qrGD_7Fho#enp+YWC=HWb)FB$Kv zJ(Q`@8vQiyBK| zd~}_`03B}rtQ{h!%!&$WlvVwY^Bz^KeY^`e*D0 zVaQDQzx4zn`--P#Zgn4NOnhV`^IxJ@Cnm*+dRbOmU1XpB8OmWnxhDWC5YHAh7?stv zM)^5>V!K3mQO&K~)?((hOZk>(0ICFddHF5D?;S3)zhRXe@DCvOupRl`V63>b8CL}( zGi$O5WhF|Q%ej!URJo9`283}9{JU}BN=uj=ci0i>Or%vYE) z9ocE3>dY2M*{d*`M)YgveSOpkaOw*AHQldDOY^bU+A?G}%*ssxm^q1w52;`RprVE~ z5MOJ!PDA67S#2MMwCS&6;oWH>6{giq#J?Hi$8*7~7>Hs|o=q`dpNaF2*-)MS41qFX zb5ZF&Da8AO*e~a^Tb*COezh%Ay+SO!%wY1WW|YzO+Mn+OH3#$k;%Q0?mxxkI$z`Q# z@kZ!2$ZrGj=JS9V+onJ^6~9-n1ex5cKJU27I$Zx;7jQt{`8xI1UovJ9SVcQnEo#f9 z4plrZTcNwFA9PPAJW&689bSn8KF#mFxw%P>Rq1OH?qzQ?_HGN??8;$JB&Vb-Lr*lI zhCwL%=_i@dAkPo0XA-~bfjA*=Xsr2StpfXj(H7o2)cO|>+AOJkK-AA8JX{aLnxd5< zr>%_vDvf$ddQ;0?TZ|BY71^%JvEjM#L^uY}wy3nnXcIzN z#n@5I^D*cq0^xRX+|C$c`ch{;x_Sp$IaN;GIcE4n3E@F-fZe>28eGE{=^eE(aK=h_ zaP9LaD~31Xg#foeD-e``*g<0Sa=vbZD*tc8u3eA#y89-#8%qIed4qw35r}EBHg`Y5 z%r2p|uV;m;Pj2d?JSF^n7`ZsN@DLv6hp%v`QMhMk-z6?=Je?%ubO!M0aT_(v=dHg! zPbzoBz?V7in*b#|D`aRjf5Sl-2hmP{5TITS60xT`X~H8O^_WHCMDVS9igy=QrncmS zk0IX39ae%~b~30y-`oOcV%%FA&^O>Xl_Qs~BpgAsUp;(AXsT7uu@+}YLJ9~Og<6EE zz*n>u<{fY^1@zKtL}X4x?Jf0IDSW?(a)#q~r`I|6gfZX$>+?JYc0f{vOC3YnIA~sP z>`WCV3v6CNh!P#vfV+_Q1eFb*>?z?vAOxf6zzVmU0_?Fh(&yP zb2Jy*G7&sH5a$5n*lr!4W`3FO))At+a-NgHzG~Spi-XQaufY681^kjOx!CNKRcWc>qu(CcNKqu-HVY2DMAr z-wxamX1bm2=e{K-p^{((B?scm-uk{W4$zfa+Pagmk zfoB1fID|CnjOsmCBXXXx&QnwQVJdgxkWCO}XHsgDV!|&FEnbM5u1oc&igOOUsONt&%1$OUGO- z)X2wLLg`7j|Jgy5wqMF>3-Ids zHIhV~$=i#dBE|PeJZ$4|?1jxCl0w!{$Mw0aAGgLO$no8XgVyl;roZ}`XRVCO&AkF_ zCuFZRe&}hpXZQ1N)NHUB!?ygG-%-RW*1;THo&tFNY5KbFma)v6$Arsejj!ZMQ?C_` z?T3H6DAoU3Mv$nbBaa|&wL*4iSJvM3LPSZ93c}+6uS5i1eLC~XPUFi^{yN`wBTT^b zGebc?nQ9AfU^}becWl4Fzm5>iIUF#xyFQnGIJxh~MMW1ZjjwkM@<%w*ZA%Ya1z6F% z7wdO95uM#Fj}kEjR-buq85>kAhobt~sutJ0DOalBgU=ivtg#{-3zCDKfd|>3#BkS`QyddPGQAOopxX7FpHhMfHts|zh+d+f`aD+H}&)Q zF|OR8(N=ziV_pquVEC{1R_*=lYk~%fiX3*93s}38z@He%jdS&0T#D_yrnqS*-T|;F z0IuFK3+E7T)DEi4aa?D}?OeC*W>lgLmriQ>7dy9u=J`ssoluzxTjP6_9NcsiF->wX zr}2&-X2{QIRZW=_Ky7+f$L-YtA7yCuDC!HDpPKbV0P?T)9NFMm+p7>GIAr!_RhpL$(!6Pg0V4ziRS4B2K9 zf!IFqKoG|!YW)SUXZgMqv(W0Nmk6Mqdsgv2>6e;9>$IOLI}Y2;!P2}R`Ppf28TLlt zTHM=vfPB3eTXM~1cdLOa=oXTIn<^ae?F4*8JLJTHZRi{e7+E=F_X7HT7L*j|u*c(m zVm_}o`tFYDq(%#1%Fa-l(hjaK)+{JuNnUzC4(cy%k^=`Y3S8 zrV6|?27*>rTO0IcFA!h@w8 zSDndmo-cV>FqB;uZv>YauL2DhCV+WBRp6jXB1s6=28qv~KM%o0-C=NK+7d)iyg~?3 zNP!32kS#%`WtpGGgJ1CE=XU^4q6HXF-7Y#t^zWeY(9zKW8sF+JB^g-+(Dy8y5gvyK|1`yd>SlOCp*ubUH7>)x7&Ec? znV0zy;_Gzn%*l+wBspU@3~EUHHJWjNoS0`ez++vF<8_IXlT%nYeqAp__bx{lP@Y+kBiEPqge$DF&&QOAh3@=u zTF+>WxnOT>-Yp>9n-uAJhPEaDDRM@Y)XwWD6jr+Tk=yk)h+|u8Yn3S4$f9D@Uiyt= z`+Vk-D}k9(PjP)P+BQgW^Ep~>oS~iP;?(QTv{I1sBkfUcNr#xj)=JTb zO&HAy++Ra#+&?P|Ge5KiegL4tJ;X_yb$C|@chX##D3975*b9a{}dv_RiS?NtbYec8~>O^kLhSWn2A zSSLw(EHw0rRk&u*iZ=-sjqZU7d1J%JOtH3R>RuP7$K0G}W`>8X;<~)Y(n_y%&sgl+ z1?T@yslcw}LWTiQUp(2(*MBFOpRUH6x(=bUKd_|goFBV$OPqkJI=%JS0W7&b*Aqlk zXnta2aVQ(4?s*q}Ba<{)9$q&Ma+e<3e9Pt_0ebFlV6qbDSRnhaIT=er@C!!7q>Dmg zU_|*;PV|Kzhe=zdp9BpD8?3JD^nZ5RH5+*HrVwe!5BV^eh9xO+<2B99r$Y z;$@nOkdBGOg?Ur;+FCz`C+iwU;RHCEG6d+!CTZ0Ojfny?v!1M&n>-PkhT-?>HH((_ z7lvHqRShUAezIDeFYF5Mk5uHb7^;!en$7E0K}8m*$q)3`H`ykIYIs(&qO!hUdJq_K z{?fBkDbu)2$}iN*qTY5H-nv-V5kwa2c#o-ZdraTRR)_ApAmPX1C8P49YNs}*5hRMb z%*8>_mBXOXWOi`dMf(E*FnLw4V zQE;tmJcg$>NBjKBV#%FC^LsxBZEp8`3$t73pF}0t+)miL%+cOftaOo9|L62qiPm`5 z^$mB(q~)4_XIah7%4Mp#(7Kzw+*B34v7ja5XzAV;ct`n;{FBJ>ge#vl)b>s?VQ0DHj^Mk4GdGMX)Di*z-75&W_#| z_AO|o_d3EV4eVR10^-&g!CaaZ-al0*20=0e2L8q53rdrFg}YBwi;hWoxEw;LKOfO6o6 z7@_bvMWv4lloV9Ll5QI;A)(jYJCaH?SRSxOSdD-2RLS`6jd$J>owMJ|fNIQdkW~5_ z0m?yqoaKO5cp~m)Nk8QzdR63;f~Ik!Yb%Mu6K=olJ>kwYK=*PaH+MmaM(f^v%YqAMCP+^ zcU8#HEZ^Vre{L;aB{-L? zRd^v@_<(fZ+}&jwDDfV$Er!Q1_gX_JitTVSGi`Otc6O`0xUld}!p-GK6E#i6!2O)^sixMMPKHJ!N}=N9 zy;jOILnYW@VFpd>wSFUJeZg1O(iT4{F6nBO6iWD@v+tqBcCX~eCF~d3(O3J3oFV18 zU-g_UQ^%cC zMU5;ij?1Ww>hvf?-lXN_Cw4a+vNM?PphH4LPU5@OwB?vsTHaoh;w5E`7BUH!E7jC2 zzSV!%Y^3;`rNDC99j|U5Nl9;q*{+|PKeM{2<_4#y)2#75J@FGhIonl_vtKA*nC}aj zSQZy|&Y&)3|MaucSo(n|?!mI#u<&$n^j&-Fs+E=J0tbK3 zy7mKV3gvU{Pl>S*=TN&nQ#jSyC#cPHxy|MF`eS41QT_0Pkl^>orCRQeb>7s_lBh%F zWbCLhveY$cSZ6z2*zOOk@*qv(KveK85r^|rP$KoaUOmmcQ?TT{#IKP$;mF@qg6n4a zSG}}D7+p&i+lPO4;z+e!kjId*c$OPDW-F&Y$N$KY5yNz6IN9h?3n$bV65n`A&zG@eI)&$;v!~>4Yv5HwJz`{rEokpTdebq z`q;!%!x9#(Poc1l1=Yb!tUShmx^epwBof&paaKcKLs_FYJ)H?{ee4k_4DzEplarIn zO_$l(Zy#kl_PT+yQLiz$u}W1;qP=M@rk?yXp-rq&i zv$MlTuEC?I0#eWYE}~Ox+fX)$h`tG<&>uRXsi5F*tEHl%a)KhnAhb4=KFq81$!@V* z(UEHzS$FvO`HPN&d;AESPGR60#^3j_Pi9sAR8Y{31Gz{dfbmxgA0zhj^YZdkMM6I$ zGY+a>4fqNLMbV=ZiO;iS9#Fjlj-`ivRfEJSt&l1bK}l@*!osr7dAW!2qGaOQVu9BjWk0kB_JTu(k0z8bP0&mAQA!+(kP6-tYT=*J26GxzE{W$F;A$?@jP4MHzft3S1BfgfII-@-+yAF$DtM*uuF9 z{Kg_Ck`)9pn~{}#rs|rwm1GyjBjdFy6HKEO!nzeI>7GW{J@>@t5bJTieOFnRtZS4` zufgJ8_d+5z2cH!@0PA51f$@a3J(U>D(B`>j5OE!JqWA--=f+W(4UQG&;o6JeQ@F$T z?prwFOfc%Odyvjrv^GpGN%3fKUli5m*JcC%^7A+MhBWdglaseM;`6@SU99U@oC2bO zKn5RU*D@4%JGoky@vk}Pfp;CHIn&>6ZGkApJ~8ak^u7W68T zoMVOeV41vP1n`sMvv#|CNP*XZU~CY`9+%lW$^ah8j1&NYd{thdzG6aPs)q0zAW-7_ zka;@3DU@FJ*oO5NpI+ZXTmBicMyT9`1F%c>w?+Qj(E9nE?aE~gTbG+MFkrj5hcp{+ z@Kf!;e!!!JQxgsgUXTWz>7EM2IFzGuigJ7@ykS}0szxILOg-T>o0)0DU-SUDNq4#^ z2|n{9OH7$xW_+^X?ay^G(f#rruJoD~p_w5qy)d8aww| zkuKBT*JRC^@*;v|{Bvc}R}K(QkdP`*PH_&=L%)(*zAZ$~S2PygG4c6tea>`66EyM1blbhnf2JpfMyzgm$bAN4{(S2q0Vg*`IQporq_t%S=VM2<6iObcZ%OyG^^t<)G73UERE1}Tw~pH$zhl{2 zPL;OD^nM#PVFFiHTLi?Vf9fV>EKK#C$E0>B@-U3*!Rymtqdi7Qk6uu}?fu&>HR+Jt z%XQl2IJJJij6ct!-PE=b^ok}*m529Z5M>#{Pabv{b^ybUprTK9kz>_-EE-24#y`P5 z^~|MLTrJM=k5X?#ALd>k`MNwUS5|nY8caw)sU1f%!PEr9!uWJAJ^A^Zib&mI+y?2> zh8mVp9N3QmYjlLPqc75CuyZVK+SVE_Hh*O#)(Y!kO4(q1gH;l>F;Z}e2#+<(6|Q9y5UKXf6R@9A64+l zv-i#kAr6H7lAx%|lg5UWUmwI2xxt*U-qzYziMWLOf4AlR8RA_k*Dafw`$YLE4@x_S z=$kcq%P(M`wKD3v?4Ae4b{?x^&Pt2UVrvxH{`IU5fa&j*Rz$WGg*4;@$mx9Nw2Ro;SWpvgVn8 zV*X=+U^bVoFOAUSJ3CsZv-vxomz4T1b>8!bNk5@G6!OwR7(A zrEPv(#6jcO{WsBor%Nn^&5f7WCv#Dg?#W~p9MWX0G;oYPidhgi2(5V{ZDxuLlE1hSTerkQRqJ+nWH;mPJqWoZop)bfCOqFzYT6XT2_`M7-rY#? zInL4$b?jmJUe7Qy?=-wMi$4!LOLld0sTK*th|$q|_Ovg!>Q+8eRYtM8LrbTM?1$Ms z)NHR$JX*VQ*16`N)c?Aw_V#Cf+u4&Heml3-F@?yLoy3a)N~(r~n6L8BslC=WvLi%2 zERL%5E1YGK#7OGz{>5994n^}*`fiUsA9Al%#m0WZxm2hp*$q<3jkY#PQJ~*bZ zn9bG8G4_+^c~M-T6vf4#^t)zDgFV{njHrFC)=K0pZg%}3C)9QJEV*TIQ?|U) zewVGwk|hQAzW(j!TD3LpGY%m8sM{ zMYw#VqatT6aNWAwy#un$9(~fC8K1EIBK#N5c`rjrJM50G+e*oorp*q@`725mrN$H8 z0pas)vw6nLkntu|n~2yIcGX9hsH4Va5uQ@SkZ{zmxsCa{DEVBeWQZ$^KFi9E&T}vmCC=yG*&7m7NDPJcE2+pJSg}NE#kj30Zn7R`z6|LfsDCmmG%uKoW0ck?;#@ew=kS+hAPTuo_isPXqGf4$Fq?K%15l87p&U!qm% zGKUvLLpBO7vWa01Lz2a;W06OrhU$IExw?F%;PHo+u7|9UWN*RX9~glW9u+x6Grj;j zVFNPEpHyit<#aTBxv77#1m^czaxOY8{^U}gPkm;!qhE4ysIfKc+{0L(Br!k%Gwb;B zcCWD5&W%_JAOGrLJ|x_&gGyppQ6>z`$q6r!Vm6WBn6#SY>4EAT^p#M()13fqEq4-1 zD%1XW0pLEG1OEF~ELEP1uyN0&!^7n36R&Drw$^(Wt;V_2yHCd;|DnMj&wiBP&C$`Jw1<4VRhy zl7sov8ISpc`T`IAt9TFFiwsx(8I`k_OM~K@ROw+Vzm)r{5jT8$w{*{4W+_vKz9J&vAZ%&EMp>v+JW+4+dPDJ?XJATO*dmO{5G zh3;^k#?~V;bR#`+4?=*GeYJ`a>Y;yGDw19Bci`(ml?9nhHVpnJB0t$Yme-tHI95s# z{*NXC4Lx$TZz*!=U~B5FiysM{yDD;Tz@0a&kD=;h=B8aG z$oQXvtA>n9%uSSu?rqAb*ss7W_MGVc^q1=9sIgMAOKdh^F6KRoo^rVAY*-$|gj;{V@2zHBT{gd!4VG+}APoW!&$aYiKDSLrR&PJL^dxEe zsw4N3tc^KDgLl!lnG`6Xd@26B=e;_2xW60NyXn~8sCGvyh}ihN>*r}Mczx%C+_Zvj zuuZYUc*>P-fy+$F!CWXo8UurIDQ*J-WN>G~Az$iG9LBqDSMNusLVr3dL#Vd6k>6w8 zVH}my5^&+-71C*x3EknifZc4J<Wlr6P|A70R|}c{YoZRY`5zzZRuk z@kvXn-zI!2kYv=@8aTh0syq7Dm#-8TDEl@#RJUCF;eNQ(l}04hiRS~)Na|?*a`vPL zSeYIHy+LiDB_}PCTu#+S__lJ&1Y#|dx++QF3&u1@4@O#uJs;sg8#1*Vpu1NuW41dAoA@K>T4O%S*GDAaeq?iy4RYClaxRIM6>DR4uobx&zt11z?QD5CnGr zdIyV4DRsk1T+<+;NVS*$x3D?pMx{2BxPNuvBAXF%T~?APJYxA$`0bAy+kcV#1LCiS zH2;>3w<8?i<3>0FG_AZC!IvKhcEJE@t^e1;|85!nPgwkC87IrIWnAMLj_NssMYtjS zOl+iKect-K&gbk*?5O?fj06!&q@V<(El@OEfCN7;>2I<;+4&rr;*(_7R&}{8i)uN> zzp0>fjsE|Q?x)|uUqmf0sr<6&uEFSEF4_hoe1L6RA=J>8+&UKQ#39H~Nh}xgDCST!*`H?igVHE`>}3d9qf#GaUbPyTj-`2XnVGxSUS z&YsV^>C36?h-94o>SGP-=pz)Q(tn-i!l0wGBCeI7!0FiiS3AAfEJeR{FrTf95j6^2 zDXb(S?44%jwQI4KGXRvU-M1jN0KvF!e^|J5?RXVm3_1~toS(Ngx)X-_v`f3C{J8v3 zCV8Gqo65HB{ASnFc4t1o;sIrQ({9I_O6#0M)1LN`ki+?esQJxnkNsD3VoG;cX5M9b zHswv-&bkYpbJH=)B?;xSm&vrqS`|SSEMpR7?-)9jxg|zI(PwpAXuJf$aLsT6WCRO8 z$O!&v3*Co!4~)6Y|30RqI%$cKNp9F(E7NETrG%=t0n$xmM5ksR_M$W!5RqVw)p!Fq zelEIGbtC|RXlrTZBH!ib=P!oEBoREK1X@=alMbo+lMP2%gbfa>H8NDEdp(PR$NVM! zOR3nzjnmIQ5ns%p?4if@jn!AZnQym`f4TJ~MybU?MCpMh*ALzR?#r5#vl{C2X6gcD zm>7y!3}q~KXe{8Ea~lYQu42SAkz=U)6=3y|`jaa<|&;FbK&l)iF=q*2!O|jkM|cB54yX%=jQZGvm1pa z>wiQ_fPubS@Bwt@YkFzjP?lA_F!~x;CLHW>DJg{d8otGs3sLC;j+_J}O|ldQaOL$D z7=}1P))nP*G49i_UAx&oFu)=&UNla88|SJ$(qHSpt-(R-dwM$do}R+|{2Hbdii(PF z&CHhBfW2^ly*kPf7t|A)WZwPtrjjGXfOr&P8|_%Lwk{SHxr@;`{Mru%fi!TRE=}mnCc688 zLJLbPySMm0Gc(h+O54Hx!Gi|`goI;TfI+ALb8DKwJ(4t$(e@>&&A5_X#mv)SH^Efa zuE-vEEJN*L#iI^+&)~F-3>V_@m=pY$mHm;TvI%w|2mz>%wl(z5%E}5XB7#M6I8*-1 z;n7ir-9l%o5ukw2)37scHDU6&BATLZa;I1f{z({Rx1WlgK62@{gttv8PVlqQy+xRy zgRXJ%cg*$18vqFM5H8q`kB?W_C8eb3yUaS1WM_+6e(0T=N_gmwWsnEhl5QF{@AG@& zNZ0M4M@#@GjN)C$(HVnKXKUl{)C_`IKMwuva#Lbqo#e8r$ov5hR{ny6(o^Z@C7Tp` z?=oK;;Tr&Yb4yH2)Tw=EVQ82-zDYkPBrJS?I$vq{=g(Luc(9?NVRCXZCWa((rJEQF z_PpKhGakfyFQwrEKV`#nd(-Fi_)bKy$m;y2h~uTv`GNhLk1{4K>EXjVFd|9}F_H4A zx}M!+i~;79=i78tjj?AL4Y%o<@jfA=*mtCD1?cG;!lB2gxzg=d%HyTcc)87YJ(=B> zth$}oUr%phTHHN*Au<^m5#bV#ZSjhbUP*4q8w0>jbI}$zARO4)*t!&5%*@Q3ohwe; zau#$r7Y)$eW&kD5M6YD3wu-z?*Mh|(095KYw#Cq3)avcTIi(vzVy z^$^4bhMHuD26UYqn?WH>DDV{VyTl`=wQ7YA$po)-(Y2BHMeAqGP1JDKQ(y> z2KNmNcod1ydY^4oH62zI6*}_LfC&GH`+uQm$G!z&W7%kbV`te=)hH^r*KZ)!I;Yg% zWw@AncBf<8ni00sKr+8ZIWqJllC7wbUr5wS_%I`Dh9lXPzn0y`GK#qFfP2=|iTYiw z6(O&1?jhw57=|wd2eBD%VAvdpF*h@#qoX4%Adn+UpT@<>%^kHyL>kOB%m;#}F7nGJ zfUky*W}!#fKes(j!4k6^mmz=>O`5FbrCpmf$DLbp^C^k(4uj)ofBEm8uT1Eyesh|- zine&JIO|eR9(-{1^15gVypv@VhXYBDOQ6xqZ|=O2g%2RaF!ESLW8SM3VduJZ zM}x}kuseM~kBGx|LW_t}MWJ$s)tJ)1achV&YMak7rE7ambJf=Ty-3ldHUX@F53k^S)G9@5JW)#Sx`nWW-<`u1<|>r({{726HlOXMULK~F&w~H}`lk2m zZ}`522YQ`mREF+5w7x2_ctDXHk3;nFHMc0W~R@1At#p>vBnSyuS-E_ zFAXrzB(|-F!f8@WG9Dk=wR|CrpxqJNbsYTzW@c7aEJR%yl>jox))_GVhz3wpwh~vs4j=QQ&<1_@DE zoC83)t}4C<_;Xip??D&IlV&%`@0>|oH$dGBYipewWOD#^+_`h-FpJvy27~~CO4{*U z&Gz2Newm#n5E>e)f4TcbA^Rrqb_=;hft`bg6bNeuvTBdsVd>7*x0r}o?^!A=3yTkH5lY9#|hi$@vtZ!q((!6=6eoryq%>85CMsIJ}IEVMUcRXTZ z^IK2_M)a%587v5aR$@{T8#{YsRiWj8dHJ2u8k;&CFE{kbz^uYP*Q_PWbz& z_h4*%4-b!);^d?x`bz$EJMm;ub|-iD+T!BkiV9OYHQ*iUFVBzbsxKoiF1$u$eQ&)7 z2hnYAZnChjOr7PrS^??)lr9D)>?Pa`*qc-$YwG?D5RYGBA)B&)oMQWZizVTQoCMH^ zGyzym@77;`Sa={>L0ZHvyuQDktP6Kj1W6-6+7?c9tfaxfkI2O zODCiRyk_pKSJ%`$p`gSR!UQpOG&lP}^7(&Pi$w!(arXg#h&buVKuJwCW!L^U?v3$ zNMA&?eX_v&*ML`ifY!}szYoTWZC#N6?B!0^b(CSUrTYv?%wY9eka{2BJ z2>_mr7ReXaFSKBJW``6bU`10m0-Is21|N7-KxJC``ev!vAm7X1&uF)U-bhLW zs^i|rfDl{+24dZWzooS;O>2K{uLS~iey|XJ1wvMD0&2W9zWW1^#uuRC7R6aVnD*` zeH3(V00%Gc?*kAP>+FO3sIk1JrY0(ic;xmCP!4QtOf4_${2>+9uFiucY{)hfz>)Ty z?q`i}0;rUrhy^$W&kbaCXz}*I5+~pi51*-$3-9auj*N`lA!X;x0J#Cubq){TbDClZ zc)|kug#*Ah-~)gI(5F?32ncW{;T8kxaN-K2?ISe!P+h<+|Hv4K5$(~{EC z=h;Lc9D*SkU{MpkAQ%HdDS$aInXOn0R6(U6#IYve2^dioDW!V*99{fmU8Q*7BJl4+hPFM z^|K%u@!xp>qUbm|IqB}kRblNm^6^R8=IjJPws8x9k^mhj3eQJLh0RrI+8za27b6rO z*601lSM5V@qA7XyRYn@GWe^jjiFvEUD6Z({(+Sku=R4M5K;r;v zqHn~RaB||dt)WKKX#YO>84k2QzM!zs#>OUIF>rH`=_ZH;$dMLk`z$<2LjhVe79x2? zT8zM#oY4%tv*eH{gpLp(Y;Hm3#DV*%qp!2^(hkTk)t&3>>l+(+0ApYSgbq(nPX~?~ z$@RqnLPOjJWn@3(Z;bo)lRq}J-h!2#eRx2b9}0!8-Mr!J-a>Qx7LXqe-#*zdLEua9 zlzxeg1ww;o@a0XQwMkTPyC48}0woRjpc2!Fd&^!0=oNouWhGfPcRvcn6`FbzS}$0< zt<+}-V9;ntd%Kjo{f2K2#qr~Z*pRuq^>7DG^}-djs36ci12|>N@?$_3v}nW{^&1&c zN&Zzp5)>44PQ&gGw!6950f1I$SJ};#`!{?Yetw8k#F7N64=(>1(_(~z_>5X$7k3hF zXHQE@%fdqHx+=)G4!N_#T~lHUUZ$4;mHkbNXOG|L!nUT=fYy-AP}8Fp8!A5 zsTlx*&&pj34ivhlr?u#(or)cul4?9po<@C~!GzfI1Cjti2?!{K7EqNiigL3TQ0>f2 z;<~Eujba3}wN~t~<=PBu#_+R4IhL^b=A#J*ZKA4CAZ!o_ zf&T_*v+tM+=cwFH~btx-zWf3)gqa|)y(L62DAieW~Kqe z_t)z4B~b$+Q3vQ)(F;?|(@7#M4GsN(Q#eJYwhp_xg4b1lkiFs%z=F<*Dk>=fp&vgt zNQd^|k@WG++YnnJ5>Bd@vd*~3YOjKV0_4^fAZ9ck5S0e*gHzZ!+!GEx2G1(8(3gq3 z1>C!!&h|-~-nXMZqGCjBNqPAwI?irp-LxvWDPDsk<^q8I)Jg1Opv|{o7XaoIfK11E zRWw;pRAgssi-td*0KlAYo3#|s9{FPwxFe=~2M?9H3lN3&_{eHrz*73P@4DVG8*HHc zL2hApx#v%4L^*nT)>l^pA;qZ+DEUXNm?Ani#eD*z0Du6?@VA@*1V+ca^#@mBEJg^S zq20jo_hPtTN-4?!&L$o$Vc5?Ue*F+rF93~d(yc&8jQHR^AW8WTnD&pUsVSf-0K~@_ zKwYc)oXSv?>n4YpYl0D#u_ymw%L``eTO&~}M$ntD-;IFOoo{U`o!HQlgc;YL zYLcr0WS~>p5dO6bKx}2>$M{(V;`q(o-(ClRW%zIb*a9xPy1Kef5rhYLsxtxw5~nT0RMUcyQytAC3SPy2sb^j`_z;K$RT2wI)I&AW{6Xr$8Tk zY?A#d?#9-vZ8eu?_~``dspNK{-UKSExmN5GwIMw42|!nTZ-kdTP44F7nVqfl{IR9@ z%Yu{VwjrF6w5H145KbvoHEjwUO{k*&O;pp+G{9qR-_eF+d{Ae)VZzc*CyM_tR=aRn z&*H;dgSdBJVk;XOTVUD2Gumb`*6?6ILgrhfroNGYM_WG6KUA0groN>$?IppDq}V6d z{B&6nUU_7cQ58)r`{dyxEt*;BD@1oihD}i}&{NlCczi^0MN+CJ z*BDNqJYD}0ulrXY5t1Dnp)p7V@YT+`6 zgR}fTsMfe^o&>sHGm}?j(hw%DH#lpcx(%=WTWOit+JzqWx|E zi;=@%xzcw_4 z-*ypm7Bqc=YivCEY$R62H2bmCqlfky@Y6t-UABpx&vSmOv`%Q(^wB%#yzUYH%(gCBc0z*g zw{4mMhsCb`uM5s8;XV2N_vrbnE%35(!cRM-Q;c4Y^}(Wodb(S0Gt}zx^UP0K0P~Y* z7t0bg4T{V>?aVDre{f?#!~3vVL-z!Uq2#qSqJQ~zC(!OH@c3+LA&BZ6=`VH((_okh zYh2XGn?})j(DoGemLsb*6r)5`<~o*VAI@v;-d}{IAT{!1z>I`n;(~bR6;O99-U0xb z&U&pKl}SUBTxP&L_oRMh7J)BYJYv0%HXtci9i+q_-s??13rERwuI&>1GPIX|t2h^? znm$USgS!NfRBGnD(%N~35=1*pUwHY6SFCZDLGEM1)lLu7m6DtN-b-AC{Z$hV(e!9P zVS>DfQ88sy#UaT7u3qTVOvtgC*e97$nsKd=)L#o27-{qbdWfQ@y!@Z{BoRnOvJF=5rSX zp(%E*V;+(&R`0Fll6ogm>`Z>npR*sGp63o3%H3jy?L6oY>$Wm& zAv%=ozR1lN5sV}!poK4+52q*cBPd^Z^2O4*nd{YbNH%$h&DvVxrR`TkFMA3k0LyB` z1^LguUkx3G#g6q`=v)g(UN86t^N)b#(aG&TO>RAqBHNIvMyEqDJJKx%SrQlO{y*LgY46vAqtK{J0l6Yfg)lt_g6iu;fALynz$F}+ZWks|THSR`cLR{u| zXZNlc=Prily-y0yD0h5p2ZxT8R_7axkJzegi)PNcSmyethQs&;%B6m{0^)M9J;pMB47Urc zyJ&T}8b52?PvH=8h;ZenWtP(PT6suLJ<=UUwH7hnM=SKT!YhrO_lWFEx+lqS?EQgg zTR39R906X6)E^Qy%F%fq@+{bA0ipXAUk=~RRnAR7L<7FMx(17lMN!1tQ3B0jY2Sp-SIy3S}bzCpj4XK+w-vx zb=8>Dg2?ldOFi!IY+S%&i9(Sjo|%X77;bJw9># z0T58>ZWV%jpDOh9BZz@BeT}xGG=jrJCyM$oKhSKA>)f(~Juq~h>=Ml4*^PV}4T!~9 zi1V>-+ltz!XEFVY_X(jLsgHh>c4(}gk?@;w?XccXH2S5tw7_I2Sd5zJ4rKR68Qx53 zHxu8c1fLWZ$5_|&xB&3pF;^Pp^YS)C^m`&RB$njHthwl9H9=k~xG1-?)%hM&cvzF@ zOad#N4E17n>Rd!U?o?piSmXgZSCYy1^lKW+O`seA+m(FBp}RHM)yhi*6>jQmJple2 z20YFyP)o44jn;T5!kfi@Yd6hYJ>pLqw3v){C0WY=kM|DC>vs#-n64~26oB;sWYK(s z`D*qL%cZhN{CFXOr7j+PoF2{}PZIJPH|50W>0PDsbzI72fDwdcnwk}GWtL|nv{Bjp z2s>Uos^V6E+y91S5}krr*>2|8q8UOUID$v9&0FD{oKn#XE;@^$5w8e0&FI|J{n(Omqc8||SL?UDz{l`Tp}umr(w47~j* z#(nnzOx=LA=h$D4ht8&2{wYywhxzb z|70FaN4g?&gWH(lyON}CCFKuA=DYJc4}r}5uOq9a55gwwiV{oj2bNSJm-MmRqrn3@ zeF79Z!vilOp;R@@rM!TWN1Jf=g}k@%^`ku|PW2TJlT}W=J4m4Q-TFZ@+Ofrd>1D@8 zX_OPm+K?06I2m%X@3goc>NlL7Zc-Ft9SXS10}{UvM41T`vk%zOPOIe~COO@s zh-EB?64X@$#N!U9xm(fw{=|DBmXkJE-H0s5Y{KzQ_I(Cz2g|E?9jCJ*si@a_&NE^~ z=Gv$DJxsE%N56531iLh_CG|VftmfCzb3g}6@khkWCqo|CEl$6v3z>Lkgt`PK%z|ZO zO6=qdsZC!LwAi zxcrDTyuX#xFP~SM}Ag zk?LxFx%{~ii-V7?v- z97)C-#DgeqJF^`b!G}iCQGoX+<3;OYW)SdgJ;-eYDz0OhZMGmjnz#2eK2}lme7>+1 z+j_Lo-Y9?^*4{qh#^-@BX{16viY@NA@W=(QLYEzM zWuvf-2xH|cH3><$f5W5>UHSvH3GsI0$fIOhG z#8*lW=a8sA3-ccpoM}KS1HI3Z>*PPZf;<9rZH52m96Vb2Fjhf5Xz|lO#Z{g^nExkG z{&={fl3js<(l>#JZX8pBRuQ5-r_A^^s zcTOxGql~KM_kYgJPB(d<7(ZW>I%iv|-7tZ7wK5g`179CXRbGX$@?wp3;}9bnNa{b% z-D6<5wAd4SkQZ!eie8%i-=*A*WLlQ@$<-MixyzS6UGZU1Wf>cRVN2RY21T+W1rln} zMomRNQd5jcx`}bos(jfTt5^O|?e)+M-E7{=g%HJHE!oMPZa7}>^M1y8GA{S1NLN+y zic+A8i&mL%;JL1hB_^Nc0mzvbbGz%|8nv~o14b(?4BFD>vWOv8vVsA~X^^auV%0WgK2#{(s5H`bJxA;O>eEP56Z+`F^F7#D&bySsFH zyiDo*-Ai%PgJffq*VnX2s0B0L5=8^rEnrv|ULdW@q+ni4D2- z6QBb|Q(Ry3gr*&KIo$*l#wJm|YivfpAT($QA=7$}K02!Wh5YS%t77~NM|ZO7Asxo{ zt+F>KZyD{^PfyTIIjqhSd>4ASW|tQesiqA{X4@@BxJ{g!kQn{q*HhFAY2hplKnuW7 z@wE1rs2MLj+^72nKd2)AP2 zEmj|?L~s#d%=eKUUvCOc{JZI&)@Gh1glbzB?|kh|0u{zQnq^AIel{}cDk=4kd6tO- z(4*-1IR~R(tFuhTHvgOy5*$f?)J>p%D+ZVoDOFaR1{Ofb{&_r06-uU68WlIqqb6aD;31p>>`6wv0QTi(}bhAeIEyhke^ZuS{Kvsbs|@!iNs)SsMG3PY%Z z$d3Cy`k|q^_XVUMy{hllKkXliNeBLAK$qxSGuU)LEgdy8>9Wlcef8uIc`VY|ZvTPi z+8@wZ`H%yGxbJs4@Xqd(pYm#Z{_=9b3w7n)emoFhNiUBSa3gCE0P{Z@2W|j3sl+6? z1^{7U=TZi!y`sIBy+7wgp6HQX#lI>v2?T1G^niaM*c)JFfFy39w&OnKWi4A3Bxs;k2fx#Y0r zn#I#Y6lSH~kxa-StnynxhPTi(6j`0`=4x+YOqF+{Rb>KE#PfW`Rn6ot1&oouP`(49 zTD$azH|})j>t8mLpwfzjZ+-dbBKWBiViTQpRBtDOtloH$W@;5m^;o+_DiBV(nrEb? z$Gby`&IJ3i)So4<3PhtGlwiP)*Uvx6HjyJF>Mi>|VRqhJxyh{s-Zkhzo^6}F$SAKMu z&Hf9q$h2;fWJ|}sc`^p~O1Vm(J{%YI+L!zWZ*MY6FOPWp2=e)1tEej*8#&A5`)@0; zmM#jaXFM##&L$l+%V*i@Sp&Bq5ij)Acd8GW)0VKhUXiYTR)}zCTOezwcRIE$2z5|h ztO#Aw7`=Z^nYP_oC`!YcLQn1|*$3!mJXi54(JR8%VV zYV$zzqOjm3!P4|SMmKL2G{_<9iz(ch@pZBzEWAv`U2tG{LN>v^U0S_aTrm{7Nt$o zemWHh*s9?y_QgujVcFEfiQ@vRUI5hR!RQX+UsSh{`jwo&)3|`*7v2qIi4gW!9x^NX zNXm~a_!wR?JKFs^Auo07R*#jb;}PpyvbD=&kO{(j==K$ZN-?g{p6$1V;9nVwCzf$!CJaKFLPR>pofSq(uovrfD zjSePRJRY@2!0Qii;Y(|9>~RKB^cBQJO|fiV%&q#jhS^SDBDtG`3EugH#wVP^!8FJj+8(*I)t_(AgTO zX8N6I?O5yh@oAl;n!qO zX7f6yc!S8z^Ij^(fD7=Lr6wFq(wR#UHAcVSkS*aM$Q%gm=-geMulu{0OI(%oR+=94 zg^X}SeyUk1<_H-cz0T2p(`l`YpiKLZ@xtZl@gPg3**FXM`Y`u(51fHqi^33|xtg3A z`1oEv+nRSb;1>TZ`ecHv zSAE3@`lW^LC!?TdjHKx zJDXBOjyu|{D$bMf)|J#43S&UyBuX9AvF$W^(fO7-EiQgWZzXR2)lzzIaIKG})$qDf zwvJSGx}fWluF0L4xR8}fOLKVsKr4w%6TSR69Z)4J$D;L_Ta0u)I&INKG?JO;i331U zPV>o%q-Kx?53(e5LgT#Q?{S*2nDDM^oVMt>OGm(2{H`kIS5*m!o)^`3fm0hKjvKq2 z5QA2&zTS0@9WCYGGQvXY(LA%`WyTZd-0H9wN#sz^JgZ@P{ncvRgRt9Wi&K)*cw>Vw zjg%l3nD;cJ{5b7@g!)@ZU5g^d*czf#J1T9ynzeEz8MwnmU#t-kr~>6jP{; zJ^S_{yEBt@_y4W=qm(hFJ5C>(|GLFqiLm0dqIHG=ee(m}^;2?niCWyPW(2X#vS6ca zIC8vfbd-Tm1AI}b6#HGKv0@J9p@i8pF!O?9CSh+icyX(yjrM$@!?o+B{MAInh#Fbd zHT#tBAxJ=T^+~Bmke{osBEw^CUnRUqLTMEjns-|-k*Uh*Mk!K$cwPgXbz4Gt^|i_u zVI8l1?b3H5yM?AuVK(c=l&yPWO<$auixH>~S=kO=hni+ZthP<)T3tOFtXcx>o)!9o zE>#RpvhXZBXKD(yZq*_z+y(C%j>>xt5e+9h#)^Kx=Tq$^n4EcQ2P%Ycn`zk+TrPWU zo|>E3kXC(xW@K@V5v2EN<*^#Mq+`qDIBuS*3HFcz`!NS?9hiYm6c|M4UvvSC3YB?cH)Ym?JKTG1OZ=mR*8m67`Vl zcSY*D@rB+H!Bn^fYQxyU^X7D($NuBew%5wdsNWh!H*LNJ6BiNSFZrc>AV+A z)>l0Nwh|iRl|&P-mm`sym`{DhRAE$a`9vR232KIA!T4a!qGGl#gZX-wWn28}b7>9W z8ydLH+&^u^qOVd}KyStS&^_^a5D*MOgwO2P0W>&QXRE9bml{hEH^u7{pQw1!1(_2ZQ%oY$3 zKI)xR5bJ+P*MdW<{Ag$dE8N?!BsJo7PLW8CGZ|}Sy?rmG%2q(TK11+Fc~kWu z(!c+}bNwq-9`ipNk^^#v^vJQofKrTWt!r7fp-Ql<`CH7i@L#&Am#;T3fs7wCOK?Ba z3=)Q}XYG_G&z+qIiQF@2fG?&7HhEBKlzfUl8ZQ_F9QU)g5HT-la;*Ynfd^j?@R(14<0Y9-wLi0yt!E1c|4{TapJ^Ifk9eH#DJRjSZCg8DiGi z$_7M>@xWS^jI+lNf#&XGvP#P7e*B5L4JD^6@U%G!a!mg)NTTU8k8zD^c*=fea{<9t zh8?-JDod}G?){?hP~RS3N5lNo{H0$m+cgSm;E*6bC5Dp)6qAlv+1LPW0pNUX$ChIU zPA27ZfVIu(L_9^;4;7#;!oMlQX$N09ezGjCffA<}9GBB?EziR!-28YvQHt%inn- z)LnNeF4jYI{! z$KxX6zFn=sj$5kyd#iuY6t{`t>4s0MaKvoAZm2y1gpE`?gL1e+RsAiosF5m)+^{ za<%Nxpak6~^7MakNHbp2GBOD)CdKwHZUC+!AaRlb83z{!hio18_D2=@=X))E;5H)-6!jrM zh8QfsI8ahoC&t4g*&TZ3e11Y%8DC#^At~Fr*K$X4s@HB;Lj-tkut}DBG!~s|eSL=1 zKn2QR$V3}3f6dFMF+2m9m6s4%u{AX!wd=w_K1xDzuCTIFp80b-AZdGGly!&|0LkVk z0BL;&b>2q;j9a>-&ykG-(#VpKbeLFJ0I6w%Biq>Y{{DXD;wPpz9e}k7enkej+ar*W zD#*{_`SaHodC!VTF#a;P;Rdt}8LB-Gz{Wp@nC8d-(0(jutKr7^=JVR z7${~RW~M9?$M*3w*tX(YrSbFmsel9vG!a6?Ry@Rgq=`qhwY33n0z7U&Pz}GSatjn? z1JwP?J}-quMEJlAUgJm=fQ*fVB-RkDAKzIPDGx6&633vSIK2YdpLoF62O~FN2OQkS z1#0<%PT*=?ot^QD()mZtk}hsrB>se; zT_B)>4EFRqLSpz5&b%KU8#56;7Ecc3izM~uz_@VE7_j=^mX<=UMbML==q-pV^YyvC zeK8XGRFLjM;pflyc_lGgIyyv$4T>k4d>ua}QXp4gNqU}B=>n-d5TAf~o|`d9vwQW5 zYwSwIi~5tqxwpi|#r#;fzxq%I7(bU&RCsm+2J1MEivW|vh=jce} zV>e!E{J_b{Nv%T$*!9FoeQ)-KgQX+ADUH?w{uL*hNc2?$lJBzaH4~~zA{!a}HS>UJ z4b&>ZlDf}l0Tmc1GKq4$^Ed1F_p6640qGKLM-N~PUtIG5QV=la1)$h7r=ZSgTAz&Z zKjqIhw$s^(7`737t2(>7y882HKj7k?3l-TM7Mj3QK00q^X68eE@h$^~3fk$8IA+s?Dx&-R+^zBi-fP8llI4Y!uKAtH))L&xkLE)f4_z?>z0Skz89>=3Z6 zdn&;S8b-m-kBIY1lsS|Fqp^)p^#YPCdTZIw1GMO}SL`3EjM&tb;dl7?!MPs5U53pr zADxrembLkb0uwgKGTNq+Sqg7eA8NEIs3!pQ-oz6jZX}|Z%Yu07zC18600`Y|eWV*w zLfXBS-=&M7Gwb(G=qxTl;FX&j8yB;&7TmB7I1ox!xWROAXo#PmALS`sUh(|wx~sMv92~I^RbW7CO+s?X z*v3XtGs1Hx#Og z>I4Iw0t+H3DG5Z9_C7VKU?W>wrAv8>pQ<`_ym^di&I%}O3rJ{xrW-oy2jx(T9Cv>I zmKH6k>SS+!Rj(9-i;Ihkii!d{us2ukk)@1)^<#;*yv*J&c#_x$b0eZun{)9x0?x>I zSWmTIUvRikP`hNxP0M-4u%pb2@>prWInVVDe!^1MVV=`nPf+RM7)d?-%&cee$-%3y zMEmZZvII{Mlj|arsWMkxh%TTh`RshkwzNsMwp1(^opz=M6H<}&5(paVR!1_O{_tfNEa;;Ei$b$;BlH{Er7?u@cr|;PnLgi6N3TgKJ!Bcq5+2#h& z67(&fvjr!T)j!Sl?1CCmsHcsBBI^@ZLqQ{`s1dPIxETijtm-0K@NwJBt6k7sp(GeJ zTwLKKPwex?7td4hkNG77I6fp6H@<8lx3FAZrY}9Z*}G5vK(Pe(Sv6nv3>gWDChEtb zvGUW!-LB&DJ*WNpWHOGeT|L{eRp}p$cf$A57_8^g_yv0ty+hr7qEnDd)~7_aK9+S~ zwz0BZB7@tM#RyeK$dE^>rZDhSb4`!-mB(Pk4D8Jlt|QEB7bD+*&*tFGK*FV=02T&R zJwqw~r;|?Wg;O!?^Tgt@hvujVH?F&*JTqcsdW5NEKD=8Mw(gx6-44~0MqvzY&Zv(f1c( z{?~G(6B1w(x&^Ht{2G=)x95o{H};8y>uhTudAcwUOF}0+TN6Cogt$^Ya+1vHniO+f zx<-xT*WfqrmMUK96HGS%(T?wd5t@no=4d3^?ORIaAHLm0d*Er9rZqA>FMwT&c8iW83&3z znr*!MXj##1_3w@F&s!t;ALKJ!5rHg%gibdLWtIk>{=(ez+1|d{s+w< zQofFge1>*meDU4Oo$B!8`n6;#0$%?`=5~9`rx!XtjJpZkOExuW9^L%#l--r)vDf8w zx`gP-IAm2%*d$G-xbx0LUD)H*PN88QLslb^ExdHI@fSa&NmrVZ<|?b0;k5HrBlMT_ zys4WSRsE$fTSXo^=)13>@(Jd-_e7~~$0_Lr2KHD4^w_96xqA3=aqX#3lW3sQ$qD|# z!eoC9PTO4_R#kmwRgu*TVFU!?PAO$Ep_?J6WW1{!JAZmzG^+X?>o!&FhvFcVCazc5 zSvZl!KY#FNdHM%2+GuS|r_}?VGNO-MVg2IiTIp^<*eH0lhIlW!R{8j)W~)&1KAPAz1+>^%4ym)*?Y)%M@D@6#2){Oj@RAI1y@fbC|U&bHYqUes(Y|K)cmXqQFoZZVqAljIN;oP+nmrK{(WpP1liceHr}*3$5Fe! z%F?`bD8=5AyR6jtu3-`9ige?M$SmWbHEo(O zV9hi(G~CzR=`hCgJB7ciXD<1^2`*yRT)*kl-v8a7K{O&1K_5G}JNqM=%yT!wH z>^E`+Li)I17HDIhf*;X(Vxm3Loi%qejM(uMINOYJ;$dYn-J#NIbePac1U_XvuWxb@`>Om zBD0)|++7AIeh~79#q3vXtB@wj9 zRsm;zfUASYMR=wnf=8T2q?O@Yh=&8?Mvv`IWg;T0`g3bQ(GCy+hNs1p??C}r z0H6XW`1cwfH6mfJ3$J4N4G&q2v690D!~a478~o z$QEGzB`G1QYmoXkh|0IW*8mU&sPy&=QQ+YeCD@I-w}Bn=1jP;e9IFJCn*f5*(;PBs zpQtKH7^cy92UV7LL3*bb#<=%f9d6@84(zIbGAGulY!ICAcG#K4EteleJxpPya9JN5 zr0k1u9m4d^bFd7us<|lWEg9U6x_RL3TPsxa0~zK_SL7{)hU?y|%IBhEe5o*D*Zb+d zsIQxJ4&ilMvXi#|Ix)0znh#INYNp4P1@$>fn!Hc};Z~bZw&L#fU)g(isA3tk zGv8YLnkMKaYt~JUl-lO9S_H~cz#|Or#vsJ_L0WAhfnw766e&zhZB)X(Hg}w}BHHkI zZ*s$eWgW$aJ)73o<7|RpaGS9W+2PK z#rlI(b0oZFKl_zD0<|j55-i>JejG^l<+<~B?B=qlbKjYx?)SW6!NvCCUBmnz>mm;v z_H}p7Uhn!EquIR&Ewsx^Km9_f=IS&f9rW|p=Lfa^9g;A%zW++!VN!N+AF9%l*@zQz3fhX8 zY7)7%LdCkyL!~ zr3~Ai*O%P&E@!oga-weZZJ7VN1F4q9FhE*2ZtPa7K-mjJs5WUZd!}uszKqIwy~J)i zz;{2-H!{36!`9`8Ohz~(pY1d5oSDCM`(M;D+qO9*K|T)q!gY6H^Q_wt1OuK{$5u-2 zOTDb<`xFaPs)OFL2_0j2zeh=f7JzXfvcn-CQ-1iZ@@HB!W$xcr^1m%MIY8m)cIfl? z$!p)NKATclDAng@&ao;ht~2T;S16ZUQDDs+ePA(WAt&JYy}F2TocwI%9g+ETR7T4Y za$+_vUMg6caPRY<_`E*GM0K!Ziods?J7TTutN-(Q^#X&;Vb2auQNd{)pIF^pkZH|e z+Ms&i^8->beq!cyF$qRuH|nE_|Fl_p&bJFO9z*b@ndEp9noaTvDiKv}k{n^Wl}`48NN z?#$NOnU|e)*SZ7Al9O!HDOb#!Sa&1uh#bi9YCw4wgKHzs9=pA0SQ4V0YT8T}1hj00 zMPBz}`C;8ZgwWUDJoAeUZ_rWc?X#6KKEmZj0Jh|}Yt?2HbqCr32+-_k7hC8g*oJ=J zt$B1^h~0#fN{`$3sS3ZbH}(ObV7=Ked~p86vvK~^Unla`idgpv=>882l1v`V<|m|? z54o!T-Za5&DmBf&gN6TuHh6f37O$Rr1N--I2rh Date: Sat, 1 Aug 2020 16:26:14 +0300 Subject: [PATCH 169/285] work on Abstract Factory readme --- abstract-factory/README.md | 53 ++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/abstract-factory/README.md b/abstract-factory/README.md index fba3460c1..141bf5021 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -9,13 +9,16 @@ tags: --- ## Also known as + Kit ## Intent + Provide an interface for creating families of related or dependent objects without specifying their concrete classes. ## Explanation + Real world example > To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. @@ -36,9 +39,11 @@ Translating the kingdom example above. First of all we have some interfaces and public interface Castle { String getDescription(); } + public interface King { String getDescription(); } + public interface Army { String getDescription(); } @@ -66,7 +71,7 @@ public class ElfArmy implements Army { } } -// Orcish implementations similarly... +// Orcish implementations similarly -> ... ``` @@ -112,9 +117,17 @@ var castle = factory.createCastle(); var king = factory.createKing(); var army = factory.createArmy(); -castle.getDescription(); // Output: This is the Elven castle! -king.getDescription(); // Output: This is the Elven king! -army.getDescription(); // Output: This is the Elven Army! +castle.getDescription(); +king.getDescription(); +army.getDescription(); +``` + +Program output: + +```java +This is the Elven castle! +This is the Elven king! +This is the Elven Army! ``` Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory. @@ -156,37 +169,39 @@ public static void main(String[] args) { ``` ## Class diagram + ![alt text](./etc/abstract-factory.urm.png "Abstract Factory class diagram") ## Applicability + Use the Abstract Factory pattern when -* a system should be independent of how its products are created, composed and represented -* a system should be configured with one of multiple families of products -* a family of related product objects is designed to be used together, and you need to enforce this constraint -* you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations -* the lifetime of the dependency is conceptually shorter than the lifetime of the consumer. -* you need a run-time value to construct a particular dependency -* you want to decide which product to call from a family at runtime. -* you need to supply one or more parameters only known at run-time before you can resolve a dependency. -* when you need consistency among products -* you don’t want to change existing code when adding new products or families of products to the program. +* The system should be independent of how its products are created, composed and represented +* The system should be configured with one of multiple families of products +* The family of related product objects is designed to be used together, and you need to enforce this constraint +* You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations +* The lifetime of the dependency is conceptually shorter than the lifetime of the consumer. +* You need a run-time value to construct a particular dependency +* You want to decide which product to call from a family at runtime. +* You need to supply one or more parameters only known at run-time before you can resolve a dependency. +* When you need consistency among products +* You don’t want to change existing code when adding new products or families of products to the program. ## Use Cases: -* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. -* Unit test case writing becomes much easier +* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. +* Unit test case writing becomes much easier * UI tools for different OS ## Consequences: -* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. +* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time. * While the pattern is great when creating predefined objects, adding the new ones might be challenging. -* The code may become more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. - +* The code becomes more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern. ## Tutorial + * [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java) From 14487261d078ef96f0dec07633c05a213ee1e1ca Mon Sep 17 00:00:00 2001 From: Matt Dolan Date: Sun, 2 Aug 2020 00:03:36 -0400 Subject: [PATCH 170/285] Use of ${artifactId} is deprecated and should be updated to ${project.artifactId} --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f23369107..65d6d3e2b 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ https://sonarcloud.io iluwatar iluwatar_java-design-patterns - ${artifactId} + ${project.artifactId} Java Design Patterns From 689cc8b59b2f1c914ef9c05841e7e9998cb0bdbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 2 Aug 2020 11:53:52 +0300 Subject: [PATCH 171/285] Update surefire and minor improvements --- pom.xml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index 65d6d3e2b..3b4f05b37 100644 --- a/pom.xml +++ b/pom.xml @@ -375,10 +375,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 - - -Xmx1024M ${argLine} - + 3.0.0-M5 org.springframework.boot @@ -474,7 +471,7 @@ true - ${projectRoot}${file.separator}license-plugin-header-style.xml + license-plugin-header-style.xml SLASHSTAR_CUSTOM_STYLE @@ -540,14 +537,4 @@ - - - - org.apache.maven.plugins - maven-jxr-plugin - 3.0.0 - - - - - \ No newline at end of file + From b0ded54c664141bfb7732579817598004cbc0399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 2 Aug 2020 22:48:54 +0300 Subject: [PATCH 172/285] Cleanup --- .../java/com/iluwatar/abstractdocument/App.java | 16 ++++------------ .../abstractdocument/AbstractDocumentTest.java | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java index b881ee7ac..d13021e72 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java @@ -43,9 +43,11 @@ public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** - * Executes the App. + * Program entry point. + * + * @param args command line args */ - public App() { + public static void main(String[] args) { LOGGER.info("Constructing parts and car"); var wheelProperties = Map.of( @@ -75,14 +77,4 @@ public class App { p.getPrice().orElse(null)) ); } - - /** - * Program entry point. - * - * @param args command line args - */ - public static void main(String[] args) { - new App(); - } - } diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java index c0791c30b..13db318e4 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AbstractDocumentTest.java @@ -40,7 +40,7 @@ public class AbstractDocumentTest { private static final String KEY = "key"; private static final String VALUE = "value"; - private class DocumentImplementation extends AbstractDocument { + private static class DocumentImplementation extends AbstractDocument { DocumentImplementation(Map properties) { super(properties); From 83acaa82d441b7373855e8c7acbcbddc2de339b9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 13:30:51 +0000 Subject: [PATCH 173/285] docs: update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 401a92103..b9509ee16 100644 --- a/README.md +++ b/README.md @@ -239,7 +239,7 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 -
Matt Dolan

💻 +
Matt Dolan

💻 👀 From f84f7b973cf955a8aae29602f2629206647c54f7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2020 13:30:52 +0000 Subject: [PATCH 174/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 50f6363e0..5e0b93860 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1045,7 +1045,8 @@ "avatar_url": "https://avatars1.githubusercontent.com/u/6307904?v=4", "profile": "https://github.com/charlesfinley", "contributions": [ - "code" + "code", + "review" ] } ], From 9ff5b9e7c09277cc51c3b26224608c699b457156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 3 Aug 2020 16:49:46 +0300 Subject: [PATCH 175/285] Fix merge --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a48db3dd2..d7115a51d 100644 --- a/README.md +++ b/README.md @@ -239,13 +239,12 @@ This project is licensed under the terms of the MIT license.
Lars Kappert

🖋
Mike Liu

🌍 -
Matt Dolan

💻 +
Matt Dolan

💻 👀
Manan

👀
Nishant Arora

💻
Peeyush

💻 -
Matt Dolan

💻 👀 From 3ae74666473dc4ee90340d810ec9e6ea6a5ae665 Mon Sep 17 00:00:00 2001 From: Rakesh Venkatesh Date: Mon, 3 Aug 2020 16:51:30 +0200 Subject: [PATCH 176/285] Typically command pattern is implemented using interfaces and concrete classes. Refactor the code to use the same --- .../src/main/java/com/iluwatar/command/Command.java | 11 +++++------ .../java/com/iluwatar/command/InvisibilitySpell.java | 2 +- .../main/java/com/iluwatar/command/ShrinkSpell.java | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/command/src/main/java/com/iluwatar/command/Command.java b/command/src/main/java/com/iluwatar/command/Command.java index 85deff74e..df91e1df3 100644 --- a/command/src/main/java/com/iluwatar/command/Command.java +++ b/command/src/main/java/com/iluwatar/command/Command.java @@ -26,15 +26,14 @@ package com.iluwatar.command; /** * Interface for Commands. */ -public abstract class Command { +public interface Command { - public abstract void execute(Target target); + public void execute(Target target); - public abstract void undo(); + public void undo(); - public abstract void redo(); + public void redo(); - @Override - public abstract String toString(); + public String toString(); } diff --git a/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java b/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java index 3e0f7bbf4..33e053cc2 100644 --- a/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java +++ b/command/src/main/java/com/iluwatar/command/InvisibilitySpell.java @@ -26,7 +26,7 @@ package com.iluwatar.command; /** * InvisibilitySpell is a concrete command. */ -public class InvisibilitySpell extends Command { +public class InvisibilitySpell implements Command { private Target target; diff --git a/command/src/main/java/com/iluwatar/command/ShrinkSpell.java b/command/src/main/java/com/iluwatar/command/ShrinkSpell.java index 87497bb7b..3f21fc7c1 100644 --- a/command/src/main/java/com/iluwatar/command/ShrinkSpell.java +++ b/command/src/main/java/com/iluwatar/command/ShrinkSpell.java @@ -26,7 +26,7 @@ package com.iluwatar.command; /** * ShrinkSpell is a concrete command. */ -public class ShrinkSpell extends Command { +public class ShrinkSpell implements Command { private Size oldSize; private Target target; From b9f17824fa026a9027d584db142b12f1f3d3c64e Mon Sep 17 00:00:00 2001 From: Rakesh Venkatesh Date: Mon, 3 Aug 2020 17:38:03 +0200 Subject: [PATCH 177/285] removing unwanted modifiers --- .../src/main/java/com/iluwatar/command/Command.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/command/src/main/java/com/iluwatar/command/Command.java b/command/src/main/java/com/iluwatar/command/Command.java index df91e1df3..83010f160 100644 --- a/command/src/main/java/com/iluwatar/command/Command.java +++ b/command/src/main/java/com/iluwatar/command/Command.java @@ -27,13 +27,11 @@ package com.iluwatar.command; * Interface for Commands. */ public interface Command { + void execute(Target target); - public void execute(Target target); + void undo(); - public void undo(); - - public void redo(); - - public String toString(); + void redo(); + String toString(); } From 44a654a2e31507cca2be00f86054dca7ac3cbf9e Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Mon, 3 Aug 2020 15:45:29 +0000 Subject: [PATCH 178/285] Resolves CR comments --- marker/src/main/java/App.java | 4 ++-- marker/src/main/java/Guard.java | 1 - marker/src/main/java/Thief.java | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/marker/src/main/java/App.java b/marker/src/main/java/App.java index 8a08a8f70..0908503e5 100644 --- a/marker/src/main/java/App.java +++ b/marker/src/main/java/App.java @@ -46,7 +46,7 @@ public class App { * @param args command line args */ public static void main(String[] args) { - final Logger logger = LoggerFactory.getLogger(App.class); + final var logger = LoggerFactory.getLogger(App.class); var guard = new Guard(); var thief = new Thief(); @@ -59,7 +59,7 @@ public class App { //noinspection ConstantConditions if (thief instanceof Permission) { - thief.doNothing(); + thief.steal(); } else { thief.doNothing(); } diff --git a/marker/src/main/java/Guard.java b/marker/src/main/java/Guard.java index 54443603c..9e7b731b6 100644 --- a/marker/src/main/java/Guard.java +++ b/marker/src/main/java/Guard.java @@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory; * Class defining Guard. */ public class Guard implements Permission { - private static final Logger LOGGER = LoggerFactory.getLogger(Guard.class); protected void enter() { diff --git a/marker/src/main/java/Thief.java b/marker/src/main/java/Thief.java index 22155ef7b..0e4cf92e3 100644 --- a/marker/src/main/java/Thief.java +++ b/marker/src/main/java/Thief.java @@ -28,10 +28,9 @@ import org.slf4j.LoggerFactory; * Class defining Thief. */ public class Thief { - private static final Logger LOGGER = LoggerFactory.getLogger(Thief.class); - protected static void steal() { + protected void steal() { LOGGER.info("Steal valuable items"); } From 054b1eaac6e79ac9bf43babca0a3521a0e4a5c04 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Mon, 3 Aug 2020 15:59:28 +0000 Subject: [PATCH 179/285] Resolves test failures --- .../model/view/controller/Fatigue.java | 5 +++-- .../iluwatar/model/view/controller/Health.java | 5 +++-- .../model/view/controller/Nourishment.java | 5 +++-- .../model/view/controller/GiantModelTest.java | 18 +++++++++--------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java index 2b7ca3999..64bae6e51 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Fatigue.java @@ -27,8 +27,9 @@ package com.iluwatar.model.view.controller; * Fatigue enumeration. */ public enum Fatigue { - - ALERT("alert"), TIRED("tired"), SLEEPING("sleeping"); + ALERT("alert"), + TIRED("tired"), + SLEEPING("sleeping"); private final String title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java index a8346b9c7..f15585cdd 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Health.java @@ -27,8 +27,9 @@ package com.iluwatar.model.view.controller; * Health enumeration. */ public enum Health { - - HEALTHY("healthy"), WOUNDED("wounded"), DEAD("dead"); + HEALTHY("healthy"), + WOUNDED("wounded"), + DEAD("dead"); private final String title; diff --git a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java index c61d2de79..ba00c38c5 100644 --- a/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java +++ b/model-view-controller/src/main/java/com/iluwatar/model/view/controller/Nourishment.java @@ -27,8 +27,9 @@ package com.iluwatar.model.view.controller; * Nourishment enumeration. */ public enum Nourishment { - - SATURATED("saturated"), HUNGRY("hungry"), STARVING("starving"); + SATURATED("saturated"), + HUNGRY("hungry"), + STARVING("starving"); private final String title; diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java index c1a86b750..677ab436e 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/GiantModelTest.java @@ -39,13 +39,13 @@ public class GiantModelTest { */ @Test public void testSetHealth() { - final var model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.HUNGRY); + final var model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); assertEquals(Health.HEALTHY, model.getHealth()); + var messageFormat = "The giant looks %s, alert and saturated."; for (final var health : Health.values()) { model.setHealth(health); assertEquals(health, model.getHealth()); - assertEquals("The giant looks " + health.toString() + ", alert and saturated.", model - .toString()); + assertEquals(String.format(messageFormat, health), model.toString()); } } @@ -54,13 +54,13 @@ public class GiantModelTest { */ @Test public void testSetFatigue() { - final var model = new GiantModel(Health.WOUNDED, Fatigue.ALERT, Nourishment.SATURATED); + final var model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); assertEquals(Fatigue.ALERT, model.getFatigue()); + var messageFormat = "The giant looks healthy, %s and saturated."; for (final var fatigue : Fatigue.values()) { model.setFatigue(fatigue); assertEquals(fatigue, model.getFatigue()); - assertEquals("The giant looks healthy, " + fatigue.toString() + " and saturated.", model - .toString()); + assertEquals(String.format(messageFormat, fatigue), model.toString()); } } @@ -69,13 +69,13 @@ public class GiantModelTest { */ @Test public void testSetNourishment() { - final var model = new GiantModel(Health.HEALTHY, Fatigue.TIRED, Nourishment.SATURATED); + final var model = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED); assertEquals(Nourishment.SATURATED, model.getNourishment()); + var messageFormat = "The giant looks healthy, alert and %s."; for (final var nourishment : Nourishment.values()) { model.setNourishment(nourishment); assertEquals(nourishment, model.getNourishment()); - assertEquals("The giant looks healthy, alert and " + nourishment.toString() + ".", model - .toString()); + assertEquals(String.format(messageFormat, nourishment), model.toString()); } } From a7b4194a71af7a1a36eca938471a1aa557cbe26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 3 Aug 2020 21:08:10 +0300 Subject: [PATCH 180/285] #590 explanation for Aggregator Microservices --- aggregator-microservices/README.md | 91 ++++++++++++++++-- .../etc/aggregator-microservice.png | Bin 41304 -> 0 bytes 2 files changed, 84 insertions(+), 7 deletions(-) delete mode 100644 aggregator-microservices/etc/aggregator-microservice.png diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md index 74a411fc5..3dd5527bc 100644 --- a/aggregator-microservices/README.md +++ b/aggregator-microservices/README.md @@ -10,16 +10,91 @@ tags: ## Intent -The user makes a single call to the Aggregator, and the aggregator then calls each relevant microservice and collects -the data, apply business logic to it, and further publish is as a REST Endpoint. -More variations of the aggregator are: -- Proxy Microservice Design Pattern: A different microservice is called upon the business need. -- Chained Microservice Design Pattern: In this case each microservice is dependent/ chained to a series -of other microservices. +The user makes a single call to the aggregator service, and the aggregator then calls each relevant microservice. + +## Explanation + +Real world example + +> Our web marketplace needs information about products and their current inventory. It makes a call to an aggregator +> service that in turn calls the product information microservice and product inventory microservice returning the +> combined information. + +In plain words + +> Aggregator Microservice collects pieces of data from various microservices and returns an aggregate for processing. + +Stack Overflow says + +> Aggregator Microservice invokes multiple services to achieve the functionality required by the application. + +**Programmatic Example** + +Let's start from the data model. Here's our `Product`. + +```java +public class Product { + private String title; + private int productInventories; + // getters and setters -> + ... +} +``` + +Next we can introduct our `Aggregator` microservice. It contains clients `ProductInformationClient` and +`ProductInventoryClient` for calling respective microservices. + +```java +@RestController +public class Aggregator { + + @Resource + private ProductInformationClient informationClient; + + @Resource + private ProductInventoryClient inventoryClient; + + @RequestMapping(path = "/product", method = RequestMethod.GET) + public Product getProduct() { + + var product = new Product(); + var productTitle = informationClient.getProductTitle(); + var productInventory = inventoryClient.getProductInventories(); + + //Fallback to error message + product.setTitle(requireNonNullElse(productTitle, "Error: Fetching Product Title Failed")); + + //Fallback to default error inventory + product.setProductInventories(requireNonNullElse(productInventory, -1)); + + return product; + } +} +``` + +Here's the essence of information microservice implementation. Inventory microservice is similar, it just returns +inventory counts. + +```java +@RestController +public class InformationController { + @RequestMapping(value = "/information", method = RequestMethod.GET) + public String getProductTitle() { + return "The Product Title."; + } +} +``` + +Now calling our `Aggregator` REST API returns the product information. + +```bash +curl http://localhost:50004/product +{"title":"The Product Title.","productInventories":5} +``` ## Class diagram -![alt text](./etc/aggregator-microservice.png "Aggregator Microservice") +![alt text](./etc/aggregator-service.png "Aggregator Microservice") ## Applicability @@ -28,3 +103,5 @@ Use the Aggregator Microservices pattern when you need a unified API for various ## Credits * [Microservice Design Patterns](http://web.archive.org/web/20190705163602/http://blog.arungupta.me/microservice-design-patterns/) +* [Microservices Patterns: With examples in Java](https://www.amazon.com/gp/product/1617294543/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617294543&linkId=8b4e570267bc5fb8b8189917b461dc60) +* [Architectural Patterns: Uncover essential patterns in the most indispensable realm of enterprise architecture](https://www.amazon.com/gp/product/B077T7V8RC/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=B077T7V8RC&linkId=c34d204bfe1b277914b420189f09c1a4) diff --git a/aggregator-microservices/etc/aggregator-microservice.png b/aggregator-microservices/etc/aggregator-microservice.png deleted file mode 100644 index ad344a7e1e0fa72633fb06e53ae4ddc0a0695ae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41304 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˂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

+0z( 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 From fa3b93bf8d899fd02f13b1902bc2eee576a9c615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 3 Aug 2020 21:25:13 +0300 Subject: [PATCH 181/285] #590 fix diagram --- aggregator-microservices/README.md | 2 +- .../etc/aggregator-service.png | Bin 0 -> 41498 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 aggregator-microservices/aggregator-service/etc/aggregator-service.png diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md index 3dd5527bc..71c4ab69a 100644 --- a/aggregator-microservices/README.md +++ b/aggregator-microservices/README.md @@ -94,7 +94,7 @@ curl http://localhost:50004/product ## Class diagram -![alt text](./etc/aggregator-service.png "Aggregator Microservice") +![alt text](./aggregator-service/etc/aggregator-service.png "Aggregator Microservice") ## Applicability diff --git a/aggregator-microservices/aggregator-service/etc/aggregator-service.png b/aggregator-microservices/aggregator-service/etc/aggregator-service.png new file mode 100644 index 0000000000000000000000000000000000000000..75ee82328bbe925e11e7175224294b925f22683e GIT binary patch literal 41498 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 literal 0 HcmV?d00001 From ca7192889dd0d00b6dba4964530110ecac6d1d26 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Mon, 3 Aug 2020 18:50:45 +0000 Subject: [PATCH 182/285] Fixes test cases for master-worker-pattern --- .../masterworker/system/systemmaster/Master.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java index 6f889edaa..a6d8966ea 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java @@ -75,7 +75,7 @@ public abstract class Master { } private void divideWork(Input input) { - List> dividedInput = input.divideData(numOfWorkers); + var dividedInput = input.divideData(numOfWorkers); if (dividedInput != null) { this.expectedNumResults = dividedInput.size(); for (var i = 0; i < this.expectedNumResults; i++) { @@ -83,6 +83,13 @@ public abstract class Master { this.workers.get(i).setReceivedData(this, dividedInput.get(i)); this.workers.get(i).start(); } + for (var i = 0; i < this.expectedNumResults; i++) { + try { + this.workers.get(i).join(); + } catch (InterruptedException e) { + System.err.println("Error while executing thread"); + } + } } } From ca58fa3f2127b8b0734875515a1df5a8561ed081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 4 Aug 2020 17:31:33 +0300 Subject: [PATCH 183/285] #590 add related patterns to Abstract Factory --- abstract-factory/README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/abstract-factory/README.md b/abstract-factory/README.md index 141bf5021..22edb81e0 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -21,7 +21,7 @@ objects without specifying their concrete classes. Real world example -> To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. +> To create a kingdom we need objects with a common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom. In plain words @@ -33,7 +33,8 @@ Wikipedia says **Programmatic Example** -Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the kingdom +Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the +kingdom. ```java public interface Castle { @@ -188,9 +189,9 @@ Use the Abstract Factory pattern when * When you need consistency among products * You don’t want to change existing code when adding new products or families of products to the program. -## Use Cases: +Example use cases -* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. +* Selecting to call to the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime. * Unit test case writing becomes much easier * UI tools for different OS @@ -204,13 +205,17 @@ Use the Abstract Factory pattern when * [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java) - -## Real world examples +## Known uses * [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html) * [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--) * [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--) +## Related patterns + +[Factory Method](https://java-design-patterns.com/patterns/factory-method/) +[Factory Kit](https://java-design-patterns.com/patterns/factory-kit/) + ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) From f234baf25839ac530d86c06cfbedbf92bb799f9e Mon Sep 17 00:00:00 2001 From: Rakesh Venkatesh Date: Tue, 4 Aug 2020 16:34:41 +0200 Subject: [PATCH 184/285] Cleanup code --- command/README.md | 15 +++++++-------- command/etc/command.png | Bin 27613 -> 77145 bytes command/etc/command.urm.puml | 10 +++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/command/README.md b/command/README.md index fc0a11d9f..b763cf4dd 100644 --- a/command/README.md +++ b/command/README.md @@ -75,19 +75,18 @@ public class Wizard { Next we present the spell hierarchy. ```java -public abstract class Command { +public interface Command { - public abstract void execute(Target target); + void execute(Target target); - public abstract void undo(); + void undo(); - public abstract void redo(); + void redo(); - @Override - public abstract String toString(); + String toString(); } -public class InvisibilitySpell extends Command { +public class InvisibilitySpell implements Command { private Target target; @@ -117,7 +116,7 @@ public class InvisibilitySpell extends Command { } } -public class ShrinkSpell extends Command { +public class ShrinkSpell implements Command { private Size oldSize; private Target target; diff --git a/command/etc/command.png b/command/etc/command.png index 81b47d6d0a0c8f7f8d92ffdece551b5377e2264f..5564b0ec52280784242f384c1f9f4ac154772f7c 100644 GIT binary patch literal 77145 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≶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 "-oldSize" Size InvisibilitySpell --> "-target" Target ShrinkSpell --> "-target" Target Target --> "-visibility" Visibility -Goblin --|> Target -InvisibilitySpell --|> Command -ShrinkSpell --|> Command -@enduml \ No newline at end of file +Goblin --|> Target +InvisibilitySpell ..|> Command +ShrinkSpell ..|> Command +@enduml From bf4706addf2b5d9cb7c0867a06b46e82216da1f9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2020 14:48:05 +0000 Subject: [PATCH 185/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7115a51d..a11ce5f89 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-118-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-119-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -245,6 +245,7 @@ This project is licensed under the terms of the MIT license.
Nishant Arora

💻
Peeyush

💻 +
Rakesh

💻 From 20a5dde8a455e332685ef8af89bbb39a399caca3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 4 Aug 2020 14:48:06 +0000 Subject: [PATCH 186/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2431125de..7f632c157 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1075,6 +1075,15 @@ "contributions": [ "code" ] + }, + { + "login": "ravening", + "name": "Rakesh", + "avatar_url": "https://avatars1.githubusercontent.com/u/10645273?v=4", + "profile": "https://github.com/ravening", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 7f29c2455f9df2167d772957eca1a89e3ba1527b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 4 Aug 2020 21:35:41 +0300 Subject: [PATCH 187/285] #590 explanation for Ambassador --- ambassador/README.md | 49 +++++++++++++++---- .../ambassador/RemoteServiceInterface.java | 2 +- proxy/README.md | 6 ++- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/ambassador/README.md b/ambassador/README.md index 11abfaf88..dfba18649 100644 --- a/ambassador/README.md +++ b/ambassador/README.md @@ -10,28 +10,37 @@ tags: --- ## Intent + Provide a helper service instance on a client and offload common functionality away from a shared resource. ## Explanation + Real world example -> A remote service has many clients accessing a function it provides. The service is a legacy application and is impossible to update. Large numbers of requests from users are causing connectivity issues. New rules for request frequency should be implemented along with latency checks and client-side logging. +> A remote service has many clients accessing a function it provides. The service is a legacy application and is +> impossible to update. Large numbers of requests from users are causing connectivity issues. New rules for request +> frequency should be implemented along with latency checks and client-side logging. In plain words -> Using the ambassador pattern, we can implement less-frequent polling from clients along with latency checks and logging. +> With the Ambassador pattern, we can implement less-frequent polling from clients along with latency checks and +> logging. Microsoft documentation states -> An ambassador service can be thought of as an out-of-process proxy that is co-located with the client. This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features. +> An ambassador service can be thought of as an out-of-process proxy which is co-located with the client. This pattern +> can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, +> security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, +> or other applications that are difficult to modify, in order to extend their networking capabilities. It can also +> enable a specialized team to implement those features. **Programmatic Example** -With the above example in mind we will imitate the functionality in a simple manner. We have an interface implemented by the remote service as well as the ambassador service: +With the above introduction in mind we will imitate the functionality in this example. We have an interface implemented +by the remote service as well as the ambassador service: ```java interface RemoteServiceInterface { - long doRemoteFunction(int value) throws Exception; } ``` @@ -136,7 +145,7 @@ public class Client { } ``` -And here are two clients using the service. +Here are two clients using the service. ```java public class App { @@ -149,13 +158,29 @@ public class App { } ``` +Here's the output for running the example: + +```java +Time taken (ms): 111 +Service result: 120 +Time taken (ms): 931 +Failed to reach remote: (1) +Time taken (ms): 665 +Failed to reach remote: (2) +Time taken (ms): 538 +Failed to reach remote: (3) +Service result: -1 +``` + ## Class diagram + ![alt text](./etc/ambassador.urm.png "Ambassador class diagram") ## Applicability -Ambassador is applicable when working with a legacy remote service that cannot -be modified or would be extremely difficult to modify. Connectivity features can -be implemented on the client avoiding the need for changes on the remote service. + +Ambassador is applicable when working with a legacy remote service which cannot be modified or would be extremely +difficult to modify. Connectivity features can be implemented on the client avoiding the need for changes on the remote +service. * Ambassador provides a local interface for a remote service. * Ambassador provides logging, circuit breaking, retries and security on the client. @@ -168,10 +193,14 @@ be implemented on the client avoiding the need for changes on the remote service * Offload remote service tasks * Facilitate network connection -## Real world examples +## Known uses * [Kubernetes-native API gateway for microservices](https://github.com/datawire/ambassador) +## Related patterns + +* [Proxy](https://java-design-patterns.com/patterns/proxy/) + ## Credits * [Ambassador pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/ambassador) diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java index 013015936..5b4995134 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java @@ -29,5 +29,5 @@ package com.iluwatar.ambassador; interface RemoteServiceInterface { int FAILURE = -1; - long doRemoteFunction(int value) throws Exception; + long doRemoteFunction(int value); } diff --git a/proxy/README.md b/proxy/README.md index b89d2a624..ddcc4e784 100644 --- a/proxy/README.md +++ b/proxy/README.md @@ -132,12 +132,16 @@ are several common situations in which the Proxy pattern is applicable * [Controlling Access With Proxy Pattern](http://java-design-patterns.com/blog/controlling-access-with-proxy-pattern/) -## Real world examples +## Known uses * [java.lang.reflect.Proxy](http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html) * [Apache Commons Proxy](https://commons.apache.org/proper/commons-proxy/) * Mocking frameworks Mockito, Powermock, EasyMock +## Related patterns + +* [Ambassador](https://java-design-patterns.com/patterns/ambassador/) + ## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59) From cd20e7a3f4b9f8a0dd30d9e7699f6c12f3f402fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 4 Aug 2020 21:45:16 +0300 Subject: [PATCH 188/285] Minor readme fixes --- acyclic-visitor/README.md | 2 +- adapter/README.md | 5 ++--- aggregator-microservices/README.md | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/acyclic-visitor/README.md b/acyclic-visitor/README.md index 19e886505..835a5743e 100644 --- a/acyclic-visitor/README.md +++ b/acyclic-visitor/README.md @@ -101,7 +101,7 @@ public class ConfigureForUnixVisitor implements ZoomVisitor { } ``` -Finally here are the visitors in action. +Finally, here are the visitors in action. ```java var conUnix = new ConfigureForUnixVisitor(); diff --git a/adapter/README.md b/adapter/README.md index 75edad180..aef4cdb69 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -12,9 +12,8 @@ tags: Wrapper ## Intent -Convert the interface of a class into another interface the clients -expect. Adapter lets classes work together that couldn't otherwise because of -incompatible interfaces. +Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that +couldn't otherwise because of incompatible interfaces. ## Explanation diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md index 71c4ab69a..36cbad33d 100644 --- a/aggregator-microservices/README.md +++ b/aggregator-microservices/README.md @@ -17,7 +17,7 @@ The user makes a single call to the aggregator service, and the aggregator then Real world example > Our web marketplace needs information about products and their current inventory. It makes a call to an aggregator -> service that in turn calls the product information microservice and product inventory microservice returning the +> service which in turn calls the product information microservice and product inventory microservice returning the > combined information. In plain words @@ -41,7 +41,7 @@ public class Product { } ``` -Next we can introduct our `Aggregator` microservice. It contains clients `ProductInformationClient` and +Next we can introduce our `Aggregator` microservice. It contains clients `ProductInformationClient` and `ProductInventoryClient` for calling respective microservices. ```java From 4b38746ce9e5777f939068691168742143bc04ce Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 4 Aug 2020 21:41:25 +0000 Subject: [PATCH 189/285] Removes usage of Dictionary --- .../iluwatar/masterworker/system/systemmaster/Master.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java index a6d8966ea..06ea3a8fe 100644 --- a/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java +++ b/master-worker-pattern/src/main/java/com/iluwatar/masterworker/system/systemmaster/Master.java @@ -26,7 +26,6 @@ package com.iluwatar.masterworker.system.systemmaster; import com.iluwatar.masterworker.Input; import com.iluwatar.masterworker.Result; import com.iluwatar.masterworker.system.systemworkers.Worker; -import java.util.Dictionary; import java.util.Hashtable; import java.util.List; @@ -40,7 +39,7 @@ import java.util.List; public abstract class Master { private final int numOfWorkers; private final List workers; - private final Dictionary> allResultData; + private final Hashtable> allResultData; private int expectedNumResults; private Result finalResult; @@ -56,7 +55,7 @@ public abstract class Master { return this.finalResult; } - Dictionary> getAllResultData() { + Hashtable> getAllResultData() { return this.allResultData; } From a7095602d6299aed284f665b67de7283826f5a39 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 4 Aug 2020 21:46:30 +0000 Subject: [PATCH 190/285] Refactors using var --- memento/README.md | 19 ++++++++++--------- .../main/java/com/iluwatar/memento/Star.java | 4 ---- .../java/com/iluwatar/memento/StarType.java | 9 ++++++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/memento/README.md b/memento/README.md index b8d95b72a..8bbebd36a 100644 --- a/memento/README.md +++ b/memento/README.md @@ -34,9 +34,12 @@ Let's first define the types of stars we are capable to handle. ```java public enum StarType { - - SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( - "dead star"), UNDEFINED(""); + SUN("sun"), + RED_GIANT("red giant"), + WHITE_DWARF("white dwarf"), + SUPERNOVA("supernova"), + DEAD("dead star"), + UNDEFINED(""); private final String title; @@ -95,8 +98,7 @@ public class Star { } StarMemento getMemento() { - - StarMementoInternal state = new StarMementoInternal(); + var state = new StarMementoInternal(); state.setAgeYears(ageYears); state.setMassTons(massTons); state.setType(type); @@ -104,8 +106,7 @@ public class Star { } void setMemento(StarMemento memento) { - - StarMementoInternal state = (StarMementoInternal) memento; + var state = (StarMementoInternal) memento; this.type = state.getType(); this.ageYears = state.getAgeYears(); this.massTons = state.getMassTons(); @@ -152,8 +153,8 @@ public class Star { And finally here's how we use the mementos to store and restore star states. ```java - Stack states = new Stack<>(); - Star star = new Star(StarType.SUN, 10000000, 500000); + var states = new Stack<>(); + var star = new Star(StarType.SUN, 10000000, 500000); LOGGER.info(star.toString()); states.add(star.getMemento()); star.timePasses(); diff --git a/memento/src/main/java/com/iluwatar/memento/Star.java b/memento/src/main/java/com/iluwatar/memento/Star.java index aac58b817..af1c98b04 100644 --- a/memento/src/main/java/com/iluwatar/memento/Star.java +++ b/memento/src/main/java/com/iluwatar/memento/Star.java @@ -70,22 +70,18 @@ public class Star { } StarMemento getMemento() { - var state = new StarMementoInternal(); state.setAgeYears(ageYears); state.setMassTons(massTons); state.setType(type); return state; - } void setMemento(StarMemento memento) { - var state = (StarMementoInternal) memento; this.type = state.getType(); this.ageYears = state.getAgeYears(); this.massTons = state.getMassTons(); - } @Override diff --git a/memento/src/main/java/com/iluwatar/memento/StarType.java b/memento/src/main/java/com/iluwatar/memento/StarType.java index 339f05f9f..aa92bf6e6 100644 --- a/memento/src/main/java/com/iluwatar/memento/StarType.java +++ b/memento/src/main/java/com/iluwatar/memento/StarType.java @@ -27,9 +27,12 @@ package com.iluwatar.memento; * StarType enumeration. */ public enum StarType { - - SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD( - "dead star"), UNDEFINED(""); + SUN("sun"), + RED_GIANT("red giant"), + WHITE_DWARF("white dwarf"), + SUPERNOVA("supernova"), + DEAD("dead star"), + UNDEFINED(""); private final String title; From 0c83ccc2fe996eba856cabfeb270445629717d18 Mon Sep 17 00:00:00 2001 From: Rakesh Venkatesh Date: Wed, 5 Aug 2020 15:50:05 +0200 Subject: [PATCH 191/285] Use enums instead os switch blocks Its better to use enums instead of switch blocks which makes the code longer and difficult to maintain as and when new state appears. --- observer/README.md | 55 +++++------------- observer/etc/observer.urm.puml | 16 ++--- observer/etc/observer_with_generics.png | Bin 0 -> 104313 bytes .../java/com/iluwatar/observer/Hobbits.java | 17 +----- .../main/java/com/iluwatar/observer/Orcs.java | 17 +----- .../com/iluwatar/observer/WeatherType.java | 15 ++++- .../iluwatar/observer/generic/GHobbits.java | 17 +----- .../com/iluwatar/observer/generic/GOrcs.java | 17 +----- .../com/iluwatar/observer/HobbitsTest.java | 8 +-- .../java/com/iluwatar/observer/OrcsTest.java | 8 +-- .../observer/generic/GHobbitsTest.java | 8 +-- .../iluwatar/observer/generic/OrcsTest.java | 8 +-- 12 files changed, 56 insertions(+), 130 deletions(-) create mode 100644 observer/etc/observer_with_generics.png diff --git a/observer/README.md b/observer/README.md index e329a657c..e4b3cea76 100644 --- a/observer/README.md +++ b/observer/README.md @@ -13,18 +13,18 @@ tags: Dependents, Publish-Subscribe ## Intent -Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified +Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. ## Explanation Real world example -> In a land far away lives the races of hobbits and orcs. Both of them are mostly outdoors so they closely follow the changes in weather. One could say that they are constantly observing the weather. +> In a land far away lives the races of hobbits and orcs. Both of them are mostly outdoors so they closely follow the changes in weather. One could say that they are constantly observing the weather. In plain words -> Register as an observer to receive state changes in the object. +> Register as an observer to receive state changes in the object. Wikipedia says @@ -46,22 +46,7 @@ public class Orcs implements WeatherObserver { @Override public void update(WeatherType currentWeather) { - switch (currentWeather) { - case COLD: - LOGGER.info("The orcs are freezing cold."); - break; - case RAINY: - LOGGER.info("The orcs are dripping wet."); - break; - case SUNNY: - LOGGER.info("The sun hurts the orcs' eyes."); - break; - case WINDY: - LOGGER.info("The orc smell almost vanishes in the wind."); - break; - default: - break; - } + LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now"); } } @@ -72,21 +57,7 @@ public class Hobbits implements WeatherObserver { @Override public void update(WeatherType currentWeather) { switch (currentWeather) { - case COLD: - LOGGER.info("The hobbits are shivering in the cold weather."); - break; - case RAINY: - LOGGER.info("The hobbits look for cover from the rain."); - break; - case SUNNY: - LOGGER.info("The happy hobbits bade in the warm sun."); - break; - case WINDY: - LOGGER.info("The hobbits hold their hats tightly in the windy weather."); - break; - default: - break; - } + LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now"); } } ``` @@ -141,20 +112,20 @@ Here's the full example in action. weather.timePasses(); // The weather changed to rainy. - // The orcs are dripping wet. - // The hobbits look for cover from the rain. + // The orcs are facing rainy weather now + // The hobbits are facing rainy weather now weather.timePasses(); // The weather changed to windy. - // The orc smell almost vanishes in the wind. - // The hobbits hold their hats tightly in the windy weather. + // The orcs are facing windy weather now + // The hobbits are facing windy weather now weather.timePasses(); // The weather changed to cold. - // The orcs are freezing cold. - // The hobbits are shivering in the cold weather. + // The orcs are facing cold weather now + // The hobbits are facing cold weather now weather.timePasses(); // The weather changed to sunny. - // The sun hurts the orcs' eyes. - // The happy hobbits bade in the warm sun. + // The orcs are facing sunny weather now + // The hobbits are facing sunny weather now ``` ## Class diagram diff --git a/observer/etc/observer.urm.puml b/observer/etc/observer.urm.puml index bea9aab53..497ef5fde 100644 --- a/observer/etc/observer.urm.puml +++ b/observer/etc/observer.urm.puml @@ -33,7 +33,9 @@ package com.iluwatar.observer { + RAINY {static} + SUNNY {static} + WINDY {static} + + description String + toString() : String + + getDescription() : String + valueOf(name : String) : WeatherType {static} + values() : WeatherType[] {static} } @@ -71,10 +73,10 @@ package com.iluwatar.observer.generic { Weather --> "-currentWeather" WeatherType GWeather --> "-currentWeather" WeatherType Weather --> "-observers" WeatherObserver -Hobbits ..|> WeatherObserver -Orcs ..|> WeatherObserver -GHobbits ..|> Race -GOrcs ..|> Race -GWeather --|> Observable -Race --|> Observer -@enduml \ No newline at end of file +Hobbits ..|> WeatherObserver +Orcs ..|> WeatherObserver +GHobbits ..|> Race +GOrcs ..|> Race +GWeather --|> Observable +Race --|> Observer +@enduml diff --git a/observer/etc/observer_with_generics.png b/observer/etc/observer_with_generics.png new file mode 100644 index 0000000000000000000000000000000000000000..06ff0d9cc246106c7ce7bb6f7fb0c7eca88c608b GIT binary patch literal 104313 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 LTx~0@&tCaArrqvR literal 0 HcmV?d00001 diff --git a/observer/src/main/java/com/iluwatar/observer/Hobbits.java b/observer/src/main/java/com/iluwatar/observer/Hobbits.java index 646ceebfd..5894c93a6 100644 --- a/observer/src/main/java/com/iluwatar/observer/Hobbits.java +++ b/observer/src/main/java/com/iluwatar/observer/Hobbits.java @@ -35,21 +35,6 @@ public class Hobbits implements WeatherObserver { @Override public void update(WeatherType currentWeather) { - switch (currentWeather) { - case COLD: - LOGGER.info("The hobbits are shivering in the cold weather."); - break; - case RAINY: - LOGGER.info("The hobbits look for cover from the rain."); - break; - case SUNNY: - LOGGER.info("The happy hobbits bade in the warm sun."); - break; - case WINDY: - LOGGER.info("The hobbits hold their hats tightly in the windy weather."); - break; - default: - break; - } + LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now"); } } diff --git a/observer/src/main/java/com/iluwatar/observer/Orcs.java b/observer/src/main/java/com/iluwatar/observer/Orcs.java index a28ffbc5b..1a955aafd 100644 --- a/observer/src/main/java/com/iluwatar/observer/Orcs.java +++ b/observer/src/main/java/com/iluwatar/observer/Orcs.java @@ -35,21 +35,6 @@ public class Orcs implements WeatherObserver { @Override public void update(WeatherType currentWeather) { - switch (currentWeather) { - case COLD: - LOGGER.info("The orcs are freezing cold."); - break; - case RAINY: - LOGGER.info("The orcs are dripping wet."); - break; - case SUNNY: - LOGGER.info("The sun hurts the orcs' eyes."); - break; - case WINDY: - LOGGER.info("The orc smell almost vanishes in the wind."); - break; - default: - break; - } + LOGGER.info("The orcs are facing " + currentWeather.getDescription() + " weather now"); } } diff --git a/observer/src/main/java/com/iluwatar/observer/WeatherType.java b/observer/src/main/java/com/iluwatar/observer/WeatherType.java index 75ee17d60..e11317c21 100644 --- a/observer/src/main/java/com/iluwatar/observer/WeatherType.java +++ b/observer/src/main/java/com/iluwatar/observer/WeatherType.java @@ -28,7 +28,20 @@ package com.iluwatar.observer; */ public enum WeatherType { - SUNNY, RAINY, WINDY, COLD; + SUNNY("Sunny"), + RAINY("Rainy"), + WINDY("Windy"), + COLD("Cold"); + + private final String description; + + WeatherType(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } @Override public String toString() { diff --git a/observer/src/main/java/com/iluwatar/observer/generic/GHobbits.java b/observer/src/main/java/com/iluwatar/observer/generic/GHobbits.java index 7a555d850..90fd4e300 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/GHobbits.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/GHobbits.java @@ -36,21 +36,6 @@ public class GHobbits implements Race { @Override public void update(GWeather weather, WeatherType weatherType) { - switch (weatherType) { - case COLD: - LOGGER.info("The hobbits are shivering in the cold weather."); - break; - case RAINY: - LOGGER.info("The hobbits look for cover from the rain."); - break; - case SUNNY: - LOGGER.info("The happy hobbits bade in the warm sun."); - break; - case WINDY: - LOGGER.info("The hobbits hold their hats tightly in the windy weather."); - break; - default: - break; - } + LOGGER.info("The hobbits are facing " + weatherType.getDescription() + " weather now"); } } diff --git a/observer/src/main/java/com/iluwatar/observer/generic/GOrcs.java b/observer/src/main/java/com/iluwatar/observer/generic/GOrcs.java index d9adbf116..bc49c4e30 100644 --- a/observer/src/main/java/com/iluwatar/observer/generic/GOrcs.java +++ b/observer/src/main/java/com/iluwatar/observer/generic/GOrcs.java @@ -36,21 +36,6 @@ public class GOrcs implements Race { @Override public void update(GWeather weather, WeatherType weatherType) { - switch (weatherType) { - case COLD: - LOGGER.info("The orcs are freezing cold."); - break; - case RAINY: - LOGGER.info("The orcs are dripping wet."); - break; - case SUNNY: - LOGGER.info("The sun hurts the orcs' eyes."); - break; - case WINDY: - LOGGER.info("The orc smell almost vanishes in the wind."); - break; - default: - break; - } + LOGGER.info("The orcs are facing " + weatherType.getDescription() + " weather now"); } } diff --git a/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java b/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java index 66ec45fdb..345b8e331 100644 --- a/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java +++ b/observer/src/test/java/com/iluwatar/observer/HobbitsTest.java @@ -36,10 +36,10 @@ public class HobbitsTest extends WeatherObserverTest { @Override public Collection dataProvider() { return List.of( - new Object[]{WeatherType.SUNNY, "The happy hobbits bade in the warm sun."}, - new Object[]{WeatherType.RAINY, "The hobbits look for cover from the rain."}, - new Object[]{WeatherType.WINDY, "The hobbits hold their hats tightly in the windy weather."}, - new Object[]{WeatherType.COLD, "The hobbits are shivering in the cold weather."}); + new Object[]{WeatherType.SUNNY, "The hobbits are facing Sunny weather now"}, + new Object[]{WeatherType.RAINY, "The hobbits are facing Rainy weather now"}, + new Object[]{WeatherType.WINDY, "The hobbits are facing Windy weather now"}, + new Object[]{WeatherType.COLD, "The hobbits are facing Cold weather now"}); } /** diff --git a/observer/src/test/java/com/iluwatar/observer/OrcsTest.java b/observer/src/test/java/com/iluwatar/observer/OrcsTest.java index ff615df3c..65beeaf0e 100644 --- a/observer/src/test/java/com/iluwatar/observer/OrcsTest.java +++ b/observer/src/test/java/com/iluwatar/observer/OrcsTest.java @@ -36,10 +36,10 @@ public class OrcsTest extends WeatherObserverTest { @Override public Collection dataProvider() { return List.of( - new Object[]{WeatherType.SUNNY, "The sun hurts the orcs' eyes."}, - new Object[]{WeatherType.RAINY, "The orcs are dripping wet."}, - new Object[]{WeatherType.WINDY, "The orc smell almost vanishes in the wind."}, - new Object[]{WeatherType.COLD, "The orcs are freezing cold."}); + new Object[]{WeatherType.SUNNY, "The orcs are facing Sunny weather now"}, + new Object[]{WeatherType.RAINY, "The orcs are facing Rainy weather now"}, + new Object[]{WeatherType.WINDY, "The orcs are facing Windy weather now"}, + new Object[]{WeatherType.COLD, "The orcs are facing Cold weather now"}); } /** diff --git a/observer/src/test/java/com/iluwatar/observer/generic/GHobbitsTest.java b/observer/src/test/java/com/iluwatar/observer/generic/GHobbitsTest.java index dd0e6d6bf..756d72239 100644 --- a/observer/src/test/java/com/iluwatar/observer/generic/GHobbitsTest.java +++ b/observer/src/test/java/com/iluwatar/observer/generic/GHobbitsTest.java @@ -38,10 +38,10 @@ public class GHobbitsTest extends ObserverTest { @Override public Collection dataProvider() { return List.of( - new Object[]{WeatherType.SUNNY, "The happy hobbits bade in the warm sun."}, - new Object[]{WeatherType.RAINY, "The hobbits look for cover from the rain."}, - new Object[]{WeatherType.WINDY, "The hobbits hold their hats tightly in the windy weather."}, - new Object[]{WeatherType.COLD, "The hobbits are shivering in the cold weather."} + new Object[]{WeatherType.SUNNY, "The hobbits are facing Sunny weather now"}, + new Object[]{WeatherType.RAINY, "The hobbits are facing Rainy weather now"}, + new Object[]{WeatherType.WINDY, "The hobbits are facing Windy weather now"}, + new Object[]{WeatherType.COLD, "The hobbits are facing Cold weather now"} ); } diff --git a/observer/src/test/java/com/iluwatar/observer/generic/OrcsTest.java b/observer/src/test/java/com/iluwatar/observer/generic/OrcsTest.java index 396de4456..523678288 100644 --- a/observer/src/test/java/com/iluwatar/observer/generic/OrcsTest.java +++ b/observer/src/test/java/com/iluwatar/observer/generic/OrcsTest.java @@ -38,10 +38,10 @@ public class OrcsTest extends ObserverTest { @Override public Collection dataProvider() { return List.of( - new Object[]{WeatherType.SUNNY, "The sun hurts the orcs' eyes."}, - new Object[]{WeatherType.RAINY, "The orcs are dripping wet."}, - new Object[]{WeatherType.WINDY, "The orc smell almost vanishes in the wind."}, - new Object[]{WeatherType.COLD, "The orcs are freezing cold."} + new Object[]{WeatherType.SUNNY, "The orcs are facing Sunny weather now"}, + new Object[]{WeatherType.RAINY, "The orcs are facing Rainy weather now"}, + new Object[]{WeatherType.WINDY, "The orcs are facing Windy weather now"}, + new Object[]{WeatherType.COLD, "The orcs are facing Cold weather now"} ); } From b0ac4c1ca3758beee3e15343c14e280d78884e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Fri, 7 Aug 2020 19:10:50 +0300 Subject: [PATCH 192/285] #590 explanation for Arrange/Act/Assert --- arrange-act-assert/README.md | 119 ++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/arrange-act-assert/README.md b/arrange-act-assert/README.md index 02b7ee8b7..6b3cb4058 100644 --- a/arrange-act-assert/README.md +++ b/arrange-act-assert/README.md @@ -9,22 +9,137 @@ tags: --- ## Also known as + Given/When/Then ## Intent -The Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. + +Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It breaks tests down into three clear and distinct steps: + 1. Arrange: Perform the setup and initialization required for the test. 2. Act: Take action(s) required for the test. 3. Assert: Verify the outcome(s) of the test. +## Explanation + +This pattern has several significant benefits. It creates a clear separation between a test's +setup, operations, and results. This structure makes the code easier to read and understand. If +you place the steps in order and format your code to separate them, you can scan a test and +quickly comprehend what it does. + +It also enforces a certain degree of discipline when you write your tests. You have to think +clearly about the three steps your test will perform. It makes tests more natural to write at +the same time since you already have an outline. + +Real world example + +> We need to write comprehensive and clear unit test suite for a class. + +In plain words + +> Arrange/Act/Assert is a testing pattern that organizes tests into three clear steps for easy +> maintenance. + +WikiWikiWeb says + +> Arrange/Act/Assert is a pattern for arranging and formatting code in UnitTest methods. + +**Programmatic Example** + +Let's first introduce our `Cash` class to be unit tested. + +```java +public class Cash { + + private int amount; + + Cash(int amount) { + this.amount = amount; + } + + void plus(int addend) { + amount += addend; + } + + boolean minus(int subtrahend) { + if (amount >= subtrahend) { + amount -= subtrahend; + return true; + } else { + return false; + } + } + + int count() { + return amount; + } +} +``` + +Then we write our unit tests according to Arrange/Act/Assert pattern. Notice the clearly +separated steps for each unit test. + +```java +public class CashAAATest { + + @Test + public void testPlus() { + //Arrange + var cash = new Cash(3); + //Act + cash.plus(4); + //Assert + assertEquals(7, cash.count()); + } + + @Test + public void testMinus() { + //Arrange + var cash = new Cash(8); + //Act + var result = cash.minus(5); + //Assert + assertTrue(result); + assertEquals(3, cash.count()); + } + + @Test + public void testInsufficientMinus() { + //Arrange + var cash = new Cash(1); + //Act + var result = cash.minus(6); + //Assert + assertFalse(result); + assertEquals(1, cash.count()); + } + + @Test + public void testUpdate() { + //Arrange + var cash = new Cash(5); + //Act + cash.plus(6); + var result = cash.minus(3); + //Assert + assertTrue(result); + assertEquals(8, cash.count()); + } +} +``` + ## Applicability + Use Arrange/Act/Assert pattern when -* you need to structure your unit tests so they're easier to read, maintain, and enhance. +* You need to structure your unit tests so that they're easier to read, maintain, and enhance. ## Credits * [Arrange, Act, Assert: What is AAA Testing?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx) * [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/) * [Martin Fowler: GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html) +* [xUnit Test Patterns: Refactoring Test Code](https://www.amazon.com/gp/product/0131495054/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0131495054&linkId=99701e8f4af2f7e8dd50d720c9b63dbf) +* [Unit Testing Principles, Practices, and Patterns](https://www.amazon.com/gp/product/1617296279/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617296279&linkId=74c75cf22a63c3e4758ae08aa0a0cc35) +* [Test Driven Development: By Example](https://www.amazon.com/gp/product/0321146530/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321146530&linkId=5c63a93d8c1175b84ca5087472ef0e05) From a5038c432963eecc876baf65734e53df78b94e26 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sat, 8 Aug 2020 00:41:58 +0000 Subject: [PATCH 193/285] Uses java-11 in naked objects --- naked-objects/dom/pom.xml | 2 +- .../homepage/HomePageViewModel.layout.json | 16 ----- .../dom/modules/simple/SimpleObject.java | 4 +- .../modules/simple/SimpleObject.layout.json | 16 ----- .../dom/modules/simple/SimpleObjectTest.java | 4 +- .../dom/modules/simple/SimpleObjectsTest.java | 6 +- .../modules/simple/SimpleObjectCreate.java | 3 +- .../scenarios/RecreateSimpleObjects.java | 21 +++++-- .../bootstrap/SimpleAppSystemInitializer.java | 7 +-- .../specglue/CatalogOfFixturesGlue.java | 5 +- .../modules/simple/SimpleObjectGlue.java | 8 +-- .../modules/simple/SimpleObjectIntegTest.java | 28 ++++----- .../simple/SimpleObjectsIntegTest.java | 60 +++++++++---------- .../webapp/ide/eclipse/launch/.gitignore | 4 -- naked-objects/webapp/pom.xml | 2 +- .../domainapp/webapp/SimpleApplication.java | 26 ++++---- .../webapp/src/main/webapp/about/index.html | 4 +- 17 files changed, 84 insertions(+), 132 deletions(-) diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index dffc1650c..0437c2da5 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -127,7 +127,7 @@ - + diff --git a/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageViewModel.layout.json b/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageViewModel.layout.json index 638473eee..fe39b5b42 100644 --- a/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageViewModel.layout.json +++ b/naked-objects/dom/src/main/java/domainapp/dom/app/homepage/HomePageViewModel.layout.json @@ -1,19 +1,3 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ { "columns": [ { diff --git a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.java b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.java index 809da6d31..43d96f280 100644 --- a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.java +++ b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.java @@ -50,9 +50,9 @@ import org.apache.isis.applib.util.ObjectContracts; strategy = javax.jdo.annotations.IdGeneratorStrategy.IDENTITY, column = "id") @javax.jdo.annotations.Version(strategy = VersionStrategy.VERSION_NUMBER, column = "version") @javax.jdo.annotations.Queries({ - @javax.jdo.annotations.Query(name = "find", language = "JDOQL", value = "SELECT " + @javax.jdo.annotations.Query(name = "find", value = "SELECT " + "FROM domainapp.dom.modules.simple.SimpleObject "), - @javax.jdo.annotations.Query(name = "findByName", language = "JDOQL", value = "SELECT " + @javax.jdo.annotations.Query(name = "findByName", value = "SELECT " + "FROM domainapp.dom.modules.simple.SimpleObject " + "WHERE name.indexOf(:name) >= 0 ")}) @javax.jdo.annotations.Unique(name = "SimpleObject_name_UNQ", members = {"name"}) @DomainObject diff --git a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.layout.json b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.layout.json index 78b2ac096..998c419f2 100644 --- a/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.layout.json +++ b/naked-objects/dom/src/main/java/domainapp/dom/modules/simple/SimpleObject.layout.json @@ -1,19 +1,3 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ { "columns": [ { diff --git a/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectTest.java b/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectTest.java index 03ab30f75..5435325cf 100644 --- a/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectTest.java +++ b/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectTest.java @@ -37,12 +37,12 @@ public class SimpleObjectTest { SimpleObject simpleObject; @Before - public void setUp() throws Exception { + public void setUp() { simpleObject = new SimpleObject(); } @Test - public void testName() throws Exception { + public void testName() { // given String name = "Foobar"; assertNull(simpleObject.getName()); diff --git a/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectsTest.java b/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectsTest.java index a95ad5aa3..5fbcfde2b 100644 --- a/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectsTest.java +++ b/naked-objects/dom/src/test/java/domainapp/dom/modules/simple/SimpleObjectsTest.java @@ -52,13 +52,13 @@ public class SimpleObjectsTest { SimpleObjects simpleObjects; @Before - public void setUp() throws Exception { + public void setUp() { simpleObjects = new SimpleObjects(); simpleObjects.container = mockContainer; } @Test - public void testCreate() throws Exception { + public void testCreate() { // given final SimpleObject simpleObject = new SimpleObject(); @@ -85,7 +85,7 @@ public class SimpleObjectsTest { } @Test - public void testListAll() throws Exception { + public void testListAll() { // given final List all = Lists.newArrayList(); diff --git a/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java b/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java index dc19195ac..0df939678 100644 --- a/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java +++ b/naked-objects/fixture/src/main/java/domainapp/fixture/modules/simple/SimpleObjectCreate.java @@ -67,8 +67,7 @@ public class SimpleObjectCreate extends FixtureScript { @Override protected void execute(final ExecutionContext ec) { - - String paramName = checkParam("name", ec, String.class); + var paramName = checkParam("name", ec, String.class); this.simpleObject = wrap(simpleObjects).create(paramName); diff --git a/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java b/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java index 847f15d01..5dc9a4785 100644 --- a/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java +++ b/naked-objects/fixture/src/main/java/domainapp/fixture/scenarios/RecreateSimpleObjects.java @@ -27,7 +27,6 @@ import com.google.common.collect.Lists; import domainapp.dom.modules.simple.SimpleObject; import domainapp.fixture.modules.simple.SimpleObjectCreate; import domainapp.fixture.modules.simple.SimpleObjectsTearDown; -import java.util.Collections; import java.util.List; import org.apache.isis.applib.fixturescripts.FixtureScript; @@ -37,8 +36,18 @@ import org.apache.isis.applib.fixturescripts.FixtureScript; */ public class RecreateSimpleObjects extends FixtureScript { - public final List names = Collections.unmodifiableList(List.of("Foo", "Bar", "Baz", - "Frodo", "Froyo", "Fizz", "Bip", "Bop", "Bang", "Boo")); + public final List names = List.of( + "Foo", + "Bar", + "Baz", + "Frodo", + "Froyo", + "Fizz", + "Bip", + "Bop", + "Bang", + "Boo" + ); // region > number (optional input) private Integer number; @@ -77,7 +86,7 @@ public class RecreateSimpleObjects extends FixtureScript { protected void execute(final ExecutionContext ec) { // defaults - final int paramNumber = defaultParam("number", ec, 3); + final var paramNumber = defaultParam("number", ec, 3); // validate if (paramNumber < 0 || paramNumber > names.size()) { @@ -90,8 +99,8 @@ public class RecreateSimpleObjects extends FixtureScript { // ec.executeChild(this, new SimpleObjectsTearDown()); - for (int i = 0; i < paramNumber; i++) { - final SimpleObjectCreate fs = new SimpleObjectCreate().setName(names.get(i)); + for (var i = 0; i < paramNumber; i++) { + final var fs = new SimpleObjectCreate().setName(names.get(i)); ec.executeChild(this, fs.getName(), fs); simpleObjects.add(fs.getSimpleObject()); } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java index f67c26876..12a187cb5 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java @@ -25,7 +25,6 @@ package domainapp.integtests.bootstrap; import org.apache.isis.core.commons.config.IsisConfiguration; import org.apache.isis.core.integtestsupport.IsisSystemForTest; -import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller; import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegTests; /** @@ -40,7 +39,7 @@ public final class SimpleAppSystemInitializer { * Init test system */ public static void initIsft() { - IsisSystemForTest isft = IsisSystemForTest.getElseNull(); + var isft = IsisSystemForTest.getElseNull(); if (isft == null) { isft = new SimpleAppSystemBuilder().build().setUpSystem(); IsisSystemForTest.set(isft); @@ -51,15 +50,13 @@ public final class SimpleAppSystemInitializer { public SimpleAppSystemBuilder() { with(testConfiguration()); - with(new DataNucleusPersistenceMechanismInstaller()); // services annotated with @DomainService withServicesIn("domainapp"); } private static IsisConfiguration testConfiguration() { - final IsisConfigurationForJdoIntegTests testConfiguration = - new IsisConfigurationForJdoIntegTests(); + final var testConfiguration = new IsisConfigurationForJdoIntegTests(); testConfiguration.addRegisterEntitiesPackagePrefix("domainapp.dom.modules"); return testConfiguration; diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/CatalogOfFixturesGlue.java b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/CatalogOfFixturesGlue.java index 025c6724a..142b0e9fb 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/CatalogOfFixturesGlue.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/CatalogOfFixturesGlue.java @@ -23,10 +23,9 @@ package domainapp.integtests.specglue; -import org.apache.isis.core.specsupport.specs.CukeGlueAbstract; - import cucumber.api.java.Before; import domainapp.fixture.scenarios.RecreateSimpleObjects; +import org.apache.isis.core.specsupport.specs.CukeGlueAbstract; /** * Test Execution to append a fixture of SimpleObjects @@ -34,7 +33,7 @@ import domainapp.fixture.scenarios.RecreateSimpleObjects; public class CatalogOfFixturesGlue extends CukeGlueAbstract { @Before(value = {"@integration", "@SimpleObjectsFixture"}, order = 20000) - public void integrationFixtures() throws Throwable { + public void integrationFixtures() { scenarioExecution().install(new RecreateSimpleObjects()); } } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java index 7b508faf3..51253b667 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/specglue/modules/simple/SimpleObjectGlue.java @@ -28,9 +28,7 @@ import static org.junit.Assert.assertThat; import cucumber.api.java.en.Given; import cucumber.api.java.en.When; -import domainapp.dom.modules.simple.SimpleObject; import domainapp.dom.modules.simple.SimpleObjects; -import java.util.List; import java.util.UUID; import org.apache.isis.core.specsupport.specs.CukeGlueAbstract; @@ -40,9 +38,9 @@ import org.apache.isis.core.specsupport.specs.CukeGlueAbstract; public class SimpleObjectGlue extends CukeGlueAbstract { @Given("^there are.* (\\d+) simple objects$") - public void thereAreNumSimpleObjects(int n) throws Throwable { + public void thereAreNumSimpleObjects(int n) { try { - final List findAll = service(SimpleObjects.class).listAll(); + final var findAll = service(SimpleObjects.class).listAll(); assertThat(findAll.size(), is(n)); putVar("list", "all", findAll); @@ -52,7 +50,7 @@ public class SimpleObjectGlue extends CukeGlueAbstract { } @When("^I create a new simple object$") - public void createNewSimpleObject() throws Throwable { + public void createNewSimpleObject() { service(SimpleObjects.class).create(UUID.randomUUID().toString()); } diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java index 11ff6a47d..819220344 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectIntegTest.java @@ -26,8 +26,10 @@ package domainapp.integtests.tests.modules.simple; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import domainapp.dom.modules.simple.SimpleObject; +import domainapp.fixture.scenarios.RecreateSimpleObjects; +import domainapp.integtests.tests.SimpleAppIntegTest; import javax.inject.Inject; - import org.apache.isis.applib.DomainObjectContainer; import org.apache.isis.applib.fixturescripts.FixtureScripts; import org.apache.isis.applib.services.wrapper.DisabledException; @@ -35,10 +37,6 @@ import org.apache.isis.applib.services.wrapper.InvalidException; import org.junit.Before; import org.junit.Test; -import domainapp.dom.modules.simple.SimpleObject; -import domainapp.fixture.scenarios.RecreateSimpleObjects; -import domainapp.integtests.tests.SimpleAppIntegTest; - /** * Test Fixtures with Simple Objects */ @@ -56,7 +54,7 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest { private static final String NEW_NAME = "new name"; @Before - public void setUp() throws Exception { + public void setUp() { // given fs = new RecreateSimpleObjects().setNumber(1); fixtureScripts.runFixtureScript(fs, null); @@ -68,15 +66,15 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest { } @Test - public void testNameAccessible() throws Exception { - // when - final String name = simpleObjectWrapped.getName(); + public void testNameAccessible() { + /* when */ + final var name = simpleObjectWrapped.getName(); // then assertEquals(fs.names.get(0), name); } @Test - public void testNameCannotBeUpdatedDirectly() throws Exception { + public void testNameCannotBeUpdatedDirectly() { // expect expectedExceptions.expect(DisabledException.class); @@ -86,7 +84,7 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest { } @Test - public void testUpdateName() throws Exception { + public void testUpdateName() { // when simpleObjectWrapped.updateName(NEW_NAME); @@ -96,7 +94,7 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest { } @Test - public void testUpdateNameFailsValidation() throws Exception { + public void testUpdateNameFailsValidation() { // expect expectedExceptions.expect(InvalidException.class); @@ -107,13 +105,13 @@ public class SimpleObjectIntegTest extends SimpleAppIntegTest { } @Test - public void testInterpolatesName() throws Exception { + public void testInterpolatesName() { // given - final String name = simpleObjectWrapped.getName(); + final var name = simpleObjectWrapped.getName(); // when - final String title = container.titleOf(simpleObjectWrapped); + final var title = container.titleOf(simpleObjectWrapped); // then assertEquals("Object: " + name, title); diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java index c762dd88f..11d108277 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java @@ -25,11 +25,13 @@ package domainapp.integtests.tests.modules.simple; import static org.junit.Assert.assertEquals; +import com.google.common.base.Throwables; +import domainapp.dom.modules.simple.SimpleObjects; +import domainapp.fixture.modules.simple.SimpleObjectsTearDown; +import domainapp.fixture.scenarios.RecreateSimpleObjects; +import domainapp.integtests.tests.SimpleAppIntegTest; import java.sql.SQLIntegrityConstraintViolationException; -import java.util.List; - import javax.inject.Inject; - import org.apache.isis.applib.fixturescripts.FixtureScript; import org.apache.isis.applib.fixturescripts.FixtureScripts; import org.hamcrest.Description; @@ -37,14 +39,6 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import org.junit.Test; -import com.google.common.base.Throwables; - -import domainapp.dom.modules.simple.SimpleObject; -import domainapp.dom.modules.simple.SimpleObjects; -import domainapp.fixture.modules.simple.SimpleObjectsTearDown; -import domainapp.fixture.scenarios.RecreateSimpleObjects; -import domainapp.integtests.tests.SimpleAppIntegTest; - /** * Fixture Pattern Integration Test */ @@ -56,25 +50,25 @@ public class SimpleObjectsIntegTest extends SimpleAppIntegTest { SimpleObjects simpleObjects; @Test - public void testListAll() throws Exception { + public void testListAll() { // given - RecreateSimpleObjects fs = new RecreateSimpleObjects(); + var fs = new RecreateSimpleObjects(); fixtureScripts.runFixtureScript(fs, null); nextTransaction(); // when - final List all = wrap(simpleObjects).listAll(); + final var all = wrap(simpleObjects).listAll(); // then assertEquals(fs.getSimpleObjects().size(), all.size()); - SimpleObject simpleObject = wrap(all.get(0)); + var simpleObject = wrap(all.get(0)); assertEquals(fs.getSimpleObjects().get(0).getName(), simpleObject.getName()); } - + @Test - public void testListAllWhenNone() throws Exception { + public void testListAllWhenNone() { // given FixtureScript fs = new SimpleObjectsTearDown(); @@ -82,14 +76,14 @@ public class SimpleObjectsIntegTest extends SimpleAppIntegTest { nextTransaction(); // when - final List all = wrap(simpleObjects).listAll(); + final var all = wrap(simpleObjects).listAll(); // then assertEquals(0, all.size()); } - + @Test - public void testCreate() throws Exception { + public void testCreate() { // given FixtureScript fs = new SimpleObjectsTearDown(); @@ -100,12 +94,12 @@ public class SimpleObjectsIntegTest extends SimpleAppIntegTest { wrap(simpleObjects).create("Faz"); // then - final List all = wrap(simpleObjects).listAll(); + final var all = wrap(simpleObjects).listAll(); assertEquals(1, all.size()); } - + @Test - public void testCreateWhenAlreadyExists() throws Exception { + public void testCreateWhenAlreadyExists() { // given FixtureScript fs = new SimpleObjectsTearDown(); @@ -115,24 +109,24 @@ public class SimpleObjectsIntegTest extends SimpleAppIntegTest { nextTransaction(); // then - expectedExceptions.expectCause(causalChainContains(SQLIntegrityConstraintViolationException.class)); + expectedExceptions + .expectCause(causalChainContains(SQLIntegrityConstraintViolationException.class)); // when wrap(simpleObjects).create("Faz"); nextTransaction(); } - + + @SuppressWarnings("SameParameterValue") private static Matcher causalChainContains(final Class cls) { - return new TypeSafeMatcher() { + return new TypeSafeMatcher<>() { @Override + @SuppressWarnings("UnstableApiUsage") protected boolean matchesSafely(Throwable item) { - final List causalChain = Throwables.getCausalChain(item); - for (Throwable throwable : causalChain) { - if (cls.isAssignableFrom(throwable.getClass())) { - return true; - } - } - return false; + final var causalChain = Throwables.getCausalChain(item); + return causalChain.stream() + .map(Throwable::getClass) + .allMatch(cls::isAssignableFrom); } @Override diff --git a/naked-objects/webapp/ide/eclipse/launch/.gitignore b/naked-objects/webapp/ide/eclipse/launch/.gitignore index 3d9734548..3cefd2567 100644 --- a/naked-objects/webapp/ide/eclipse/launch/.gitignore +++ b/naked-objects/webapp/ide/eclipse/launch/.gitignore @@ -2,7 +2,3 @@ /SimpleApp-PROTOTYPE-no-fixtures.launch /SimpleApp-PROTOTYPE-with-fixtures.launch /SimpleApp-SERVER-no-fixtures.launch -/SimpleApp-PROTOTYPE-jrebel.launch -/SimpleApp-PROTOTYPE-no-fixtures.launch -/SimpleApp-PROTOTYPE-with-fixtures.launch -/SimpleApp-SERVER-no-fixtures.launch diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index bdf638cba..bbddeb791 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -129,7 +129,7 @@ - + diff --git a/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java b/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java index 8425712dc..780e4027e 100644 --- a/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java +++ b/naked-objects/webapp/src/main/java/domainapp/webapp/SimpleApplication.java @@ -31,18 +31,15 @@ import com.google.inject.name.Names; import com.google.inject.util.Modules; import com.google.inject.util.Providers; import de.agilecoders.wicket.core.Bootstrap; -import de.agilecoders.wicket.core.settings.IBootstrapSettings; import de.agilecoders.wicket.themes.markup.html.bootswatch.BootswatchTheme; import de.agilecoders.wicket.themes.markup.html.bootswatch.BootswatchThemeProvider; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; -import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.isis.viewer.wicket.viewer.IsisWicketApplication; import org.apache.isis.viewer.wicket.viewer.integration.wicket.AuthenticatedWebSessionForIsis; import org.apache.wicket.Session; -import org.apache.wicket.request.IRequestParameters; import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; import org.apache.wicket.request.http.WebRequest; @@ -85,7 +82,7 @@ public class SimpleApplication extends IsisWicketApplication { protected void init() { super.init(); - IBootstrapSettings settings = Bootstrap.getSettings(); + var settings = Bootstrap.getSettings(); settings.setThemeProvider(new BootswatchThemeProvider(BootswatchTheme.Flatly)); } @@ -96,13 +93,10 @@ public class SimpleApplication extends IsisWicketApplication { } // else demo mode - final AuthenticatedWebSessionForIsis s = - (AuthenticatedWebSessionForIsis) super.newSession(request, response); - IRequestParameters requestParameters = request.getRequestParameters(); - final org.apache.wicket.util.string.StringValue user = - requestParameters.getParameterValue("user"); - final org.apache.wicket.util.string.StringValue password = - requestParameters.getParameterValue("pass"); + final var s = (AuthenticatedWebSessionForIsis) super.newSession(request, response); + var requestParameters = request.getRequestParameters(); + final var user = requestParameters.getParameterValue("user"); + final var password = requestParameters.getParameterValue("pass"); s.signIn(user.toString(), password.toString()); return s; } @@ -115,7 +109,7 @@ public class SimpleApplication extends IsisWicketApplication { // else demo mode try { - String uname = servletRequest.getParameter("user"); + var uname = servletRequest.getParameter("user"); if (uname != null) { servletRequest.getSession().invalidate(); } @@ -127,7 +121,7 @@ public class SimpleApplication extends IsisWicketApplication { @Override protected Module newIsisWicketModule() { - final Module isisDefaults = super.newIsisWicketModule(); + final var isisDefaults = super.newIsisWicketModule(); final Module overrides = new AbstractModule() { @Override @@ -148,11 +142,11 @@ public class SimpleApplication extends IsisWicketApplication { return Modules.override(isisDefaults).with(overrides); } + @SuppressWarnings({"UnstableApiUsage", "SameParameterValue"}) private static String readLines(final Class contextClass, final String resourceName) { try { - List readLines = - Resources.readLines(Resources.getResource(contextClass, resourceName), - Charset.defaultCharset()); + var resource = Resources.getResource(contextClass, resourceName); + var readLines = Resources.readLines(resource, Charset.defaultCharset()); return Joiner.on("\n").join(readLines); } catch (IOException e) { return "This is a simple app"; diff --git a/naked-objects/webapp/src/main/webapp/about/index.html b/naked-objects/webapp/src/main/webapp/about/index.html index e929c5b6d..4579f3d0b 100644 --- a/naked-objects/webapp/src/main/webapp/about/index.html +++ b/naked-objects/webapp/src/main/webapp/about/index.html @@ -110,8 +110,8 @@ th, td {

provides access to a RESTful API conformant with the - Restful Objects spec. This is part of Apache Isis Core. The - implementation technology is JBoss RestEasy. + Restful Objects spec. This is part of Apache Isis Core. + The implementation technology is JBoss RestEasy.

From 8e060ad0adafb059108820bb4af3b528374eece7 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sat, 8 Aug 2020 00:46:08 +0000 Subject: [PATCH 194/285] Refactors null object pattern to java-11 --- .../java/com/iluwatar/nullobject/App.java | 16 ++++--- .../java/com/iluwatar/nullobject/AppTest.java | 6 +-- .../com/iluwatar/nullobject/NullNodeTest.java | 4 +- .../com/iluwatar/nullobject/TreeTest.java | 45 +++++++++---------- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/null-object/src/main/java/com/iluwatar/nullobject/App.java b/null-object/src/main/java/com/iluwatar/nullobject/App.java index 2826bafd0..00cff9fc9 100644 --- a/null-object/src/main/java/com/iluwatar/nullobject/App.java +++ b/null-object/src/main/java/com/iluwatar/nullobject/App.java @@ -37,12 +37,16 @@ public class App { * @param args command line args */ public static void main(String[] args) { - - Node root = - new NodeImpl("1", new NodeImpl("11", new NodeImpl("111", NullNode.getInstance(), - NullNode.getInstance()), NullNode.getInstance()), new NodeImpl("12", - NullNode.getInstance(), new NodeImpl("122", NullNode.getInstance(), - NullNode.getInstance()))); + Node root = new NodeImpl("1", + new NodeImpl("11", + new NodeImpl("111", NullNode.getInstance(), NullNode.getInstance()), + NullNode.getInstance() + ), + new NodeImpl("12", + NullNode.getInstance(), + new NodeImpl("122", NullNode.getInstance(), NullNode.getInstance()) + ) + ); root.walk(); } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java b/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java index 97d6b5eef..754aadc80 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java @@ -26,15 +26,11 @@ package com.iluwatar.nullobject; import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { - @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java b/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java index b4d9f72d0..aeec371ff 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java @@ -42,14 +42,14 @@ public class NullNodeTest { */ @Test public void testGetInstance() { - final NullNode instance = NullNode.getInstance(); + final var instance = NullNode.getInstance(); assertNotNull(instance); assertSame(instance, NullNode.getInstance()); } @Test public void testFields() { - final NullNode node = NullNode.getInstance(); + final var node = NullNode.getInstance(); assertEquals(0, node.getTreeSize()); assertNull(node.getName()); assertNull(node.getLeft()); diff --git a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java index 3fe584425..9a2b485d0 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/TreeTest.java @@ -23,22 +23,21 @@ package com.iluwatar.nullobject; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.AppenderBase; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; - -import java.util.LinkedList; -import java.util.List; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import java.util.LinkedList; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; + /** * Date: 12/26/15 - 11:44 PM * @@ -75,12 +74,12 @@ public class TreeTest { private static final Node TREE_ROOT; static { - final NodeImpl level1B = new NodeImpl("level1_b", NullNode.getInstance(), NullNode.getInstance()); - final NodeImpl level2B = new NodeImpl("level2_b", NullNode.getInstance(), NullNode.getInstance()); - final NodeImpl level3A = new NodeImpl("level3_a", NullNode.getInstance(), NullNode.getInstance()); - final NodeImpl level3B = new NodeImpl("level3_b", NullNode.getInstance(), NullNode.getInstance()); - final NodeImpl level2A = new NodeImpl("level2_a", level3A, level3B); - final NodeImpl level1A = new NodeImpl("level1_a", level2A, level2B); + final var level1B = new NodeImpl("level1_b", NullNode.getInstance(), NullNode.getInstance()); + final var level2B = new NodeImpl("level2_b", NullNode.getInstance(), NullNode.getInstance()); + final var level3A = new NodeImpl("level3_a", NullNode.getInstance(), NullNode.getInstance()); + final var level3B = new NodeImpl("level3_b", NullNode.getInstance(), NullNode.getInstance()); + final var level2A = new NodeImpl("level2_a", level3A, level3B); + final var level1A = new NodeImpl("level1_a", level2A, level2B); TREE_ROOT = new NodeImpl("root", level1A, level1B); } @@ -112,17 +111,17 @@ public class TreeTest { @Test public void testGetLeft() { - final Node level1 = TREE_ROOT.getLeft(); + final var level1 = TREE_ROOT.getLeft(); assertNotNull(level1); assertEquals("level1_a", level1.getName()); assertEquals(5, level1.getTreeSize()); - final Node level2 = level1.getLeft(); + final var level2 = level1.getLeft(); assertNotNull(level2); assertEquals("level2_a", level2.getName()); assertEquals(3, level2.getTreeSize()); - final Node level3 = level2.getLeft(); + final var level3 = level2.getLeft(); assertNotNull(level3); assertEquals("level3_a", level3.getName()); assertEquals(1, level3.getTreeSize()); @@ -132,7 +131,7 @@ public class TreeTest { @Test public void testGetRight() { - final Node level1 = TREE_ROOT.getRight(); + final var level1 = TREE_ROOT.getRight(); assertNotNull(level1); assertEquals("level1_b", level1.getName()); assertEquals(1, level1.getTreeSize()); @@ -140,7 +139,7 @@ public class TreeTest { assertSame(NullNode.getInstance(), level1.getLeft()); } - private class InMemoryAppender extends AppenderBase { + private static class InMemoryAppender extends AppenderBase { private final List log = new LinkedList<>(); public InMemoryAppender() { @@ -154,7 +153,7 @@ public class TreeTest { } public boolean logContains(String message) { - return log.stream().anyMatch(event -> event.getMessage().equals(message)); + return log.stream().map(ILoggingEvent::getMessage).anyMatch(message::equals); } public int getLogSize() { From 8b92bc6bb6ea58a2eaa1a14bb5b3eb66bd82b6cc Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Sat, 8 Aug 2020 00:53:30 +0000 Subject: [PATCH 195/285] Corrects README.md --- null-object/README.md | 15 ++++++++++----- .../main/java/com/iluwatar/nullobject/App.java | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/null-object/README.md b/null-object/README.md index 5b943630e..f5d92a7fc 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -141,11 +141,16 @@ public final class NullNode implements Node { Then we can construct and traverse the binary tree without errors as follows. ```java - Node root = - new NodeImpl("1", new NodeImpl("11", new NodeImpl("111", NullNode.getInstance(), - NullNode.getInstance()), NullNode.getInstance()), new NodeImpl("12", - NullNode.getInstance(), new NodeImpl("122", NullNode.getInstance(), - NullNode.getInstance()))); + var root = new NodeImpl("1", + new NodeImpl("11", + new NodeImpl("111", NullNode.getInstance(), NullNode.getInstance()), + NullNode.getInstance() + ), + new NodeImpl("12", + NullNode.getInstance(), + new NodeImpl("122", NullNode.getInstance(), NullNode.getInstance()) + ) + ); root.walk(); // 1 diff --git a/null-object/src/main/java/com/iluwatar/nullobject/App.java b/null-object/src/main/java/com/iluwatar/nullobject/App.java index 00cff9fc9..cd35a3042 100644 --- a/null-object/src/main/java/com/iluwatar/nullobject/App.java +++ b/null-object/src/main/java/com/iluwatar/nullobject/App.java @@ -37,7 +37,7 @@ public class App { * @param args command line args */ public static void main(String[] args) { - Node root = new NodeImpl("1", + var root = new NodeImpl("1", new NodeImpl("11", new NodeImpl("111", NullNode.getInstance(), NullNode.getInstance()), NullNode.getInstance() From fa68789cd5dc902de71d049d67beccca96c35aaf Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sat, 8 Aug 2020 15:49:14 +0530 Subject: [PATCH 196/285] #1321 Updated readme and add UML diagram --- transaction-script/Readme.md | 111 +++++++++++++++--- transaction-script/etc/transaction-script.png | Bin 0 -> 73666 bytes 2 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 transaction-script/etc/transaction-script.png diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 0d0383c44..87cd138f6 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -11,33 +11,110 @@ tags: ## Intent Transaction script(TS) is mainly used in small applications where nothing complex is done and bigger architecture's are not needed. -## Name / classification -... - -## Also known as -... - - ## Explanation -... +Real world example +> Your need is to be able to book a hotel room and also be able to cancel that booking. +> + +In plain words +> All logic related to booking a hotel room like checking room availability, +> calculate rates and update the database is done inside a single transaction script. +> Similar procedure is also needed for cancelling a room booking and all +> that logic will be in another transaction script. + +Programmatic example + +The Hotel class takes care of booking and cancelling a room in a hotel. + +```java +public class Hotel { + private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + + private HotelDaoImpl hotelDao; + + public Hotel(HotelDaoImpl hotelDao) { + this.hotelDao = hotelDao; + } + + public void bookRoom(int roomNumber) throws Exception { + + Optional room = hotelDao.getById(roomNumber); + + if (room.isEmpty()) { + throw new Exception("Room number: " + roomNumber + " does not exist"); + } else { + if (room.get().isBooked()) { + throw new Exception("Room already booked!"); + } else { + Room updateRoomBooking = room.get(); + updateRoomBooking.setBooked(true); + hotelDao.update(updateRoomBooking); + } + } + } + + public void cancelRoomBooking(int roomNumber) throws Exception { + + Optional room = hotelDao.getById(roomNumber); + + if (room.isEmpty()) { + throw new Exception("Room number: " + roomNumber + " does not exist"); + } else { + if (room.get().isBooked()) { + Room updateRoomBooking = room.get(); + updateRoomBooking.setBooked(false); + int refundAmount = updateRoomBooking.getPrice(); + hotelDao.update(updateRoomBooking); + + LOGGER.info("Booking cancelled for room number: " + roomNumber); + LOGGER.info(refundAmount + " is refunded"); + } else { + throw new Exception("No booking for the room exists"); + } + } + } +} +``` + +This class has two methods, one for booking and cancelling a room respectively. + +``` +public void bookRoom(int roomNumber); +``` +The book room method consolidates all the needed steps like checking if the room is already booked +or not, if not booked then books the rooma nd updates the database by using the DAO. + +``` +public void cancelRoomBooking(int roomNumber) +``` +The cancel room method consolidates steps like checking if the room is booked or not, +if booked then calculates the refund amount and updates the database using the DAO. ## Class diagram -... +![alt text](./etc/transaction-script.png "Transaction script model") ## Applicability -... +Use the transaction script model when the application has only a small amount of logic and that +logic won't be extended in the future. -## Tutorials -... ## Known uses -... +* Revenue recognition in business systems. -## Consequences (the good and the bad, add criticism here) -... +## Consequences +* As the business logic gets more complicated, +it gets progressively harder to keep the transaction script +in a well-designed state. +* Code duplication between transaction scripts can occur. +* Normally not easy to refactor transactions script to other domain logic +patterns. ## Related patterns -... +* Domain Model +* Table Module +* Service Layer ## Credits -... +* [Transaction Script Pattern](https://dzone.com/articles/transaction-script-pattern#:~:text=Transaction%20Script%20(TS)%20is%20the,need%20big%20architecture%20behind%20them.) +* [Transaction Script](https://www.informit.com/articles/article.aspx?p=1398617) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420?ie=UTF8&tag=gupesasnebl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321127420) diff --git a/transaction-script/etc/transaction-script.png b/transaction-script/etc/transaction-script.png new file mode 100644 index 0000000000000000000000000000000000000000..f3561f84db3661cff40d2624c47b512b0075fea1 GIT binary patch literal 73666 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

KG$TPq}zSN=T>~v>;V?kB()7t?0 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

LHtYf0@(17keXrW-K)X;+#pRxH;4E{20GH;*8_q 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 Date: Sat, 8 Aug 2020 11:56:34 +0000 Subject: [PATCH 197/285] Corrects condition --- .../integtests/bootstrap/SimpleAppSystemInitializer.java | 2 ++ .../tests/modules/simple/SimpleObjectsIntegTest.java | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java index 12a187cb5..ad186d706 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java @@ -25,6 +25,7 @@ package domainapp.integtests.bootstrap; import org.apache.isis.core.commons.config.IsisConfiguration; import org.apache.isis.core.integtestsupport.IsisSystemForTest; +import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller; import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegTests; /** @@ -50,6 +51,7 @@ public final class SimpleAppSystemInitializer { public SimpleAppSystemBuilder() { with(testConfiguration()); + with(new DataNucleusPersistenceMechanismInstaller()); // services annotated with @DomainService withServicesIn("domainapp"); diff --git a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java index 11d108277..2699c5aad 100644 --- a/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java +++ b/naked-objects/integtests/src/test/java/domainapp/integtests/tests/modules/simple/SimpleObjectsIntegTest.java @@ -124,9 +124,7 @@ public class SimpleObjectsIntegTest extends SimpleAppIntegTest { @SuppressWarnings("UnstableApiUsage") protected boolean matchesSafely(Throwable item) { final var causalChain = Throwables.getCausalChain(item); - return causalChain.stream() - .map(Throwable::getClass) - .allMatch(cls::isAssignableFrom); + return causalChain.stream().map(Throwable::getClass).anyMatch(cls::isAssignableFrom); } @Override From 1f6e6f34ea22f22259e63c746dc0dfca5b704172 Mon Sep 17 00:00:00 2001 From: Wei Seng Date: Sun, 9 Aug 2020 03:09:53 +0800 Subject: [PATCH 198/285] Update README.md --- private-class-data/README.md | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/private-class-data/README.md b/private-class-data/README.md index 20e343285..0cd771bab 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -13,6 +13,106 @@ Private Class Data design pattern seeks to reduce exposure of attributes by limiting their visibility. It reduces the number of class attributes by encapsulating them in single Data object. +## Explanation + +Real world example + +> Imagine you are cooking a stew for your family for dinner.You want to prevent your family members from comsuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. +In plain words + +> Private class data pattern prevent manipulation of data that is meant to be immutable by seperating the data from methods that use it into a class that maintains the data state. +Wikipedia says + +> Private class data is a design pattern in computer programming used to encapsulate class attributes and their manipulation. +**Programmatic Example** + +Taking our stew example from above. First we have a Stew class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. + +``` +public class Stew { + private static final Logger LOGGER = LoggerFactory.getLogger(Stew.class); + private int numPotatoes; + private int numCarrots; + private int numMeat; + private int numPeppers; + public Stew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + this.numPotatoes = numPotatoes; + this.numCarrots = numCarrots; + this.numMeat = numMeat; + this.numPeppers = numPeppers; + } + public void mix() { + LOGGER.info("Mixing the stew we find: {} potatoes, {} carrots, {} meat and {} peppers", + numPotatoes, numCarrots, numMeat, numPeppers); + } + public void taste() { + LOGGER.info("Tasting the stew"); + if (numPotatoes > 0) { + numPotatoes--; + } + if (numCarrots > 0) { + numCarrots--; + } + if (numMeat > 0) { + numMeat--; + } + if (numPeppers > 0) { + numPeppers--; + } + } +} +``` + +Now, we have ImmutableStew class, where its ingredient is protected by StewData class so methods are unable to manipulate the data of the stew. +``` +public class StewData { + private final int numPotatoes; + private final int numCarrots; + private final int numMeat; + private final int numPeppers; + public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + this.numPotatoes = numPotatoes; + this.numCarrots = numCarrots; + this.numMeat = numMeat; + this.numPeppers = numPeppers; + } + public int getNumPotatoes() { + return numPotatoes; + } + public int getNumCarrots() { + return numCarrots; + } + public int getNumMeat() { + return numMeat; + } + public int getNumPeppers() { + return numPeppers; + } +} +public class ImmutableStew { + private static final Logger LOGGER = LoggerFactory.getLogger(ImmutableStew.class); + private final StewData data; + public ImmutableStew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) { + data = new StewData(numPotatoes, numCarrots, numMeat, numPeppers); + } + public void mix() { + LOGGER + .info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers", + data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers()); + } +} +``` + +Let's try creating some instance of each class and calling their methods +``` +var stew = new Stew(1, 2, 3, 4); +stew.mix(); // Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers +stew.taste(); // Tasting the stew +stew.mix(); // Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers +var immutableStew = new ImmutableStew(2, 4, 3, 6); +immutableStew.mix(); // Mixing the immutable stew we find: 2 potatoes, 4 carrots, 3 meat and 6 peppers +``` + ## Class diagram ![alt text](./etc/private-class-data.png "Private Class Data") From 08cec0e254edd54bc4947d3e6c4bb5b044867edd Mon Sep 17 00:00:00 2001 From: Wei Seng Date: Sun, 9 Aug 2020 03:10:43 +0800 Subject: [PATCH 199/285] Update README.md --- private-class-data/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/private-class-data/README.md b/private-class-data/README.md index 0cd771bab..b751c4fe9 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -18,12 +18,15 @@ attributes by encapsulating them in single Data object. Real world example > Imagine you are cooking a stew for your family for dinner.You want to prevent your family members from comsuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. + In plain words > Private class data pattern prevent manipulation of data that is meant to be immutable by seperating the data from methods that use it into a class that maintains the data state. + Wikipedia says > Private class data is a design pattern in computer programming used to encapsulate class attributes and their manipulation. + **Programmatic Example** Taking our stew example from above. First we have a Stew class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. From 50ed5ca699fa11e9bc6f71c67385b562211bc3d5 Mon Sep 17 00:00:00 2001 From: Wei Seng Date: Sun, 9 Aug 2020 03:15:26 +0800 Subject: [PATCH 200/285] Some minor spelling error in comment --- .../test/java/com/iluwatar/module/FileLoggerModuleTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java index 6497aa89d..9899d4c5c 100644 --- a/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java +++ b/module/src/test/java/com/iluwatar/module/FileLoggerModuleTest.java @@ -63,7 +63,7 @@ public final class FileLoggerModuleTest { @Test public void testFileMessage() throws IOException { - /* Get singletong instance of File Logger Module */ + /* Get singleton instance of File Logger Module */ final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ @@ -109,7 +109,7 @@ public final class FileLoggerModuleTest { @Test public void testFileErrorMessage() throws FileNotFoundException { - /* Get singletong instance of File Logger Module */ + /* Get singleton instance of File Logger Module */ final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ @@ -134,7 +134,7 @@ public final class FileLoggerModuleTest { @Test public void testNoFileErrorMessage() throws FileNotFoundException { - /* Get singletong instance of File Logger Module */ + /* Get singleton instance of File Logger Module */ final var fileLoggerModule = FileLoggerModule.getSingleton(); /* Prepare the essential sub modules, to perform the sequence of jobs */ From 9f190c59c4615b50374e511f9a0de0aeb0033539 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 9 Aug 2020 00:51:28 +0530 Subject: [PATCH 201/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 87cd138f6..ed010f919 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -1,6 +1,6 @@ --- layout: pattern -title: Transaction script +title: Transaction Script folder: transaction-script permalink: /patterns/transaction-script/ categories: Domain logic From c0acaf073be6abd861ac76d66ce151a1572464eb Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 9 Aug 2020 00:51:36 +0530 Subject: [PATCH 202/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index ed010f919..6fcae7791 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -3,7 +3,7 @@ layout: pattern title: Transaction Script folder: transaction-script permalink: /patterns/transaction-script/ -categories: Domain logic +categories: Behavioral tags: - Data access --- From 5bfaeffecf4a66563a2a23f6fee889a180e26c3c Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Sun, 9 Aug 2020 00:51:44 +0530 Subject: [PATCH 203/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 6fcae7791..0b7f209c2 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -9,7 +9,7 @@ tags: --- ## Intent -Transaction script(TS) is mainly used in small applications where nothing complex is done and bigger architecture's are not needed. +Transaction Script organizes business logic by procedures where each procedure handles a single request from the presentation. ## Explanation Real world example From c40d6ae9d7d94172c5232a2bfc7cb97eba3b4b20 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:44:03 +0000 Subject: [PATCH 204/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a11ce5f89..c8daddbda 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-119-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-120-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -246,6 +246,7 @@ This project is licensed under the terms of the MIT license.
Nishant Arora

💻
Peeyush

💻
Rakesh

💻 +
Wei Seng

💻 From b8c0985b972f2e357af42459a06db2ed94079aa7 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:44:04 +0000 Subject: [PATCH 205/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7f632c157..135cb1260 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1084,6 +1084,15 @@ "contributions": [ "code" ] + }, + { + "login": "vINCENT8888801", + "name": "Wei Seng", + "avatar_url": "https://avatars0.githubusercontent.com/u/8037883?v=4", + "profile": "https://github.com/vINCENT8888801", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 7acc5fbf957ae6143890097e11f2f4ef683d3f6d Mon Sep 17 00:00:00 2001 From: Ashish_Trivedi Date: Sun, 9 Aug 2020 01:33:19 +0530 Subject: [PATCH 206/285] #1321 Resolved conflicts and used var wherever possible --- pom.xml | 1 + .../transactionscript/Hotel.java | 10 +++--- .../transactionscript/HotelDaoImpl.java | 33 +++++++++---------- ...CustomException.java => SqlException.java} | 8 ++--- .../TransactionScriptApp.java | 11 +++---- .../transactionscript/HotelTest.java | 5 ++- 6 files changed, 33 insertions(+), 35 deletions(-) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{CustomException.java => SqlException.java} (88%) diff --git a/pom.xml b/pom.xml index 38d8e97db..3c909312b 100644 --- a/pom.xml +++ b/pom.xml @@ -372,6 +372,7 @@ 11 11 + 3.0.0-M3 org.apache.maven.plugins diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index 58705e5e6..8a756f99c 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -44,7 +44,7 @@ public class Hotel { */ public void bookRoom(int roomNumber) throws Exception { - Optional room = hotelDao.getById(roomNumber); + var room = hotelDao.getById(roomNumber); if (room.isEmpty()) { throw new Exception("Room number: " + roomNumber + " does not exist"); @@ -52,7 +52,7 @@ public class Hotel { if (room.get().isBooked()) { throw new Exception("Room already booked!"); } else { - Room updateRoomBooking = room.get(); + var updateRoomBooking = room.get(); updateRoomBooking.setBooked(true); hotelDao.update(updateRoomBooking); } @@ -66,14 +66,14 @@ public class Hotel { * @throws Exception if any error */ public void cancelRoomBooking(int roomNumber) throws Exception { - - Optional room = hotelDao.getById(roomNumber); + + var room = hotelDao.getById(roomNumber); if (room.isEmpty()) { throw new Exception("Room number: " + roomNumber + " does not exist"); } else { if (room.get().isBooked()) { - Room updateRoomBooking = room.get(); + var updateRoomBooking = room.get(); updateRoomBooking.setBooked(false); int refundAmount = updateRoomBooking.getPrice(); hotelDao.update(updateRoomBooking); diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java index f1b509416..e95363fb5 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java @@ -26,7 +26,6 @@ package com.ashishtrivedi16.transactionscript; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.SQLException; import java.util.Optional; import java.util.Spliterator; import java.util.Spliterators; @@ -48,7 +47,7 @@ public class HotelDaoImpl implements HotelDao { try { var connection = getConnection(); var statement = connection.prepareStatement("SELECT * FROM ROOMS"); - ResultSet resultSet = statement.executeQuery(); // NOSONAR + var resultSet = statement.executeQuery(); // NOSONAR return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) { @@ -60,7 +59,7 @@ public class HotelDaoImpl implements HotelDao { } action.accept(createRoom(resultSet)); return true; - } catch (SQLException e) { + } catch (Exception e) { throw new RuntimeException(e); // NOSONAR } } @@ -71,8 +70,8 @@ public class HotelDaoImpl implements HotelDao { e.printStackTrace(); } }); - } catch (SQLException e) { - throw new CustomException(e.getMessage(), e); + } catch (Exception e) { + throw new SqlException(e.getMessage(), e); } } @@ -90,8 +89,8 @@ public class HotelDaoImpl implements HotelDao { } else { return Optional.empty(); } - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); + } catch (Exception ex) { + throw new SqlException(ex.getMessage(), ex); } finally { if (resultSet != null) { resultSet.close(); @@ -113,8 +112,8 @@ public class HotelDaoImpl implements HotelDao { statement.setBoolean(4, room.isBooked()); statement.execute(); return true; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); + } catch (Exception ex) { + throw new SqlException(ex.getMessage(), ex); } } @@ -130,8 +129,8 @@ public class HotelDaoImpl implements HotelDao { statement.setBoolean(3, room.isBooked()); statement.setInt(4, room.getId()); return statement.executeUpdate() > 0; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); + } catch (Exception ex) { + throw new SqlException(ex.getMessage(), ex); } } @@ -141,12 +140,12 @@ public class HotelDaoImpl implements HotelDao { var statement = connection.prepareStatement("DELETE FROM ROOMS WHERE ID = ?")) { statement.setInt(1, room.getId()); return statement.executeUpdate() > 0; - } catch (SQLException ex) { - throw new CustomException(ex.getMessage(), ex); + } catch (Exception ex) { + throw new SqlException(ex.getMessage(), ex); } } - private Connection getConnection() throws SQLException { + private Connection getConnection() throws Exception { return dataSource.getConnection(); } @@ -156,12 +155,12 @@ public class HotelDaoImpl implements HotelDao { resultSet.close(); statement.close(); connection.close(); - } catch (SQLException e) { - throw new CustomException(e.getMessage(), e); + } catch (Exception e) { + throw new SqlException(e.getMessage(), e); } } - private Room createRoom(ResultSet resultSet) throws SQLException { + private Room createRoom(ResultSet resultSet) throws Exception { return new Room(resultSet.getInt("ID"), resultSet.getString("ROOM_TYPE"), resultSet.getInt("PRICE"), diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java similarity index 88% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java index 002ea79aa..369eb259d 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/CustomException.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java @@ -26,18 +26,18 @@ package com.ashishtrivedi16.transactionscript; /** * Custom exception. */ -public class CustomException extends Exception { +public class SqlException extends Exception { private static final long serialVersionUID = 1L; - public CustomException() { + public SqlException() { } - public CustomException(String message) { + public SqlException(String message) { super(message); } - public CustomException(String message, Throwable cause) { + public SqlException(String message, Throwable cause) { super(message, cause); } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java index 13a19dd48..e49e1d501 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java @@ -23,7 +23,6 @@ package com.ashishtrivedi16.transactionscript; -import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.h2.jdbcx.JdbcDataSource; @@ -51,8 +50,8 @@ public class TransactionScriptApp { addRooms(dao); getRoomStatus(dao); - - Hotel hotel = new Hotel(dao); + + var hotel = new Hotel(dao); hotel.bookRoom(1); hotel.bookRoom(2); @@ -77,7 +76,7 @@ public class TransactionScriptApp { } } - private static void deleteSchema(DataSource dataSource) throws SQLException { + private static void deleteSchema(DataSource dataSource) throws java.sql.SQLException { try (var connection = dataSource.getConnection(); var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); @@ -89,7 +88,7 @@ public class TransactionScriptApp { var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); } catch (Exception e) { - throw new CustomException(e.getMessage(), e); + throw new SqlException(e.getMessage(), e); } } @@ -99,7 +98,7 @@ public class TransactionScriptApp { * @return h2 datasource */ private static DataSource createDataSource() { - JdbcDataSource dataSource = new JdbcDataSource(); + var dataSource = new JdbcDataSource(); dataSource.setUrl(H2_DB_URL); return dataSource; } diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java index 62aad9527..86f4605b3 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java @@ -28,7 +28,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import javax.sql.DataSource; -import java.sql.SQLException; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -103,7 +102,7 @@ public class HotelTest { } - private static void deleteSchema(DataSource dataSource) throws SQLException { + private static void deleteSchema(DataSource dataSource) throws java.sql.SQLException { try (var connection = dataSource.getConnection(); var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.DELETE_SCHEMA_SQL); @@ -115,7 +114,7 @@ public class HotelTest { var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); } catch (Exception e) { - throw new CustomException(e.getMessage(), e); + throw new SqlException(e.getMessage(), e); } } From a59c9bba97a2af0d175da0929fa7295371ddaadf Mon Sep 17 00:00:00 2001 From: Ashish_Trivedi Date: Sun, 9 Aug 2020 01:39:51 +0530 Subject: [PATCH 207/285] #1321 --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3c909312b..4853d762f 100644 --- a/pom.xml +++ b/pom.xml @@ -367,7 +367,6 @@ org.apache.maven.plugins maven-compiler-plugin - ${compiler.version} 11 11 From e09de2fb360b65b6c0438cd328a616ccf67f3b76 Mon Sep 17 00:00:00 2001 From: Ashish_Trivedi Date: Sun, 9 Aug 2020 01:58:19 +0530 Subject: [PATCH 208/285] #1321 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4853d762f..38d8e97db 100644 --- a/pom.xml +++ b/pom.xml @@ -367,11 +367,11 @@ org.apache.maven.plugins maven-compiler-plugin + ${compiler.version} 11 11 - 3.0.0-M3 org.apache.maven.plugins From f4fa73cd481797898ff8c75045fc4813fe205400 Mon Sep 17 00:00:00 2001 From: Wei Seng Date: Sun, 9 Aug 2020 16:28:40 +0800 Subject: [PATCH 209/285] Update README.md Increase clarity --- private-class-data/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/private-class-data/README.md b/private-class-data/README.md index b751c4fe9..0a3e33b08 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -17,7 +17,7 @@ attributes by encapsulating them in single Data object. Real world example -> Imagine you are cooking a stew for your family for dinner.You want to prevent your family members from comsuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. +> Imagine you are cooking a stew for your family for dinner. You want to prevent your family members from comsuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. In plain words @@ -66,7 +66,7 @@ public class Stew { } ``` -Now, we have ImmutableStew class, where its ingredient is protected by StewData class so methods are unable to manipulate the data of the stew. +Now, we have ImmutableStew class, where its data is protected by StewData class. Now, the methods in are unable to manipulate the data of the ImmutableStew class. ``` public class StewData { private final int numPotatoes; From 700f5c6d277a7d12f3b54622eae0c880e71ead56 Mon Sep 17 00:00:00 2001 From: Wei Seng Date: Sun, 9 Aug 2020 18:22:40 +0800 Subject: [PATCH 210/285] corrected some typo --- private-class-data/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/private-class-data/README.md b/private-class-data/README.md index 0a3e33b08..a105cac34 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -17,11 +17,11 @@ attributes by encapsulating them in single Data object. Real world example -> Imagine you are cooking a stew for your family for dinner. You want to prevent your family members from comsuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. +> Imagine you are cooking a stew for your family for dinner. You want to prevent your family members from consuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. In plain words -> Private class data pattern prevent manipulation of data that is meant to be immutable by seperating the data from methods that use it into a class that maintains the data state. +> Private class data pattern prevent manipulation of data that is meant to be immutable by separating the data from methods that use it into a class that maintains the data state. Wikipedia says @@ -29,7 +29,7 @@ Wikipedia says **Programmatic Example** -Taking our stew example from above. First we have a Stew class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. +Taking our stew example from above. First we have a `Stew` class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. ``` public class Stew { @@ -66,7 +66,7 @@ public class Stew { } ``` -Now, we have ImmutableStew class, where its data is protected by StewData class. Now, the methods in are unable to manipulate the data of the ImmutableStew class. +Now, we have `ImmutableStew` class, where its data is protected by `StewData` class. Now, the methods in are unable to manipulate the data of the `ImmutableStew` class. ``` public class StewData { private final int numPotatoes; From d219a104c76363c8edb782836174c77a19bc2ff7 Mon Sep 17 00:00:00 2001 From: Amit Garg Date: Sun, 9 Aug 2020 14:18:41 +0100 Subject: [PATCH 211/285] Add logging in API Gateway --- .../iluwatar/api/gateway/ImageClientImpl.java | 23 +++++++++++++++++- .../iluwatar/api/gateway/PriceClientImpl.java | 24 ++++++++++++++++++- .../image/microservice/ImageController.java | 6 +++++ .../price/microservice/PriceController.java | 6 +++++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java index 52dd065ff..6fea815fc 100644 --- a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java +++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/ImageClientImpl.java @@ -23,11 +23,16 @@ package com.iluwatar.api.gateway; +import static org.slf4j.LoggerFactory.getLogger; + import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; + +import org.slf4j.Logger; import org.springframework.stereotype.Component; /** @@ -35,6 +40,8 @@ import org.springframework.stereotype.Component; */ @Component public class ImageClientImpl implements ImageClient { + private static final Logger LOGGER = getLogger(ImageClientImpl.class); + /** * Makes a simple HTTP Get request to the Image microservice. * @@ -49,12 +56,26 @@ public class ImageClientImpl implements ImageClient { .build(); try { + LOGGER.info("Sending request to fetch image path"); var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString()); + logResponse(httpResponse); return httpResponse.body(); } catch (IOException | InterruptedException e) { - e.printStackTrace(); + LOGGER.error("Failure occurred while getting image path", e); } return null; } + + private void logResponse(HttpResponse httpResponse) { + if (isSuccessResponse(httpResponse.statusCode())) { + LOGGER.info("Image path received successfully"); + } else { + LOGGER.warn("Image path request failed"); + } + } + + private boolean isSuccessResponse(int responseCode) { + return responseCode >= 200 && responseCode <= 299; + } } diff --git a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java index 0dc44a51b..f773d0d54 100644 --- a/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java +++ b/api-gateway/api-gateway-service/src/main/java/com/iluwatar/api/gateway/PriceClientImpl.java @@ -23,18 +23,26 @@ package com.iluwatar.api.gateway; +import static org.slf4j.LoggerFactory.getLogger; + import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; + +import org.slf4j.Logger; import org.springframework.stereotype.Component; + /** * An adapter to communicate with the Price microservice. */ @Component public class PriceClientImpl implements PriceClient { + private static final Logger LOGGER = getLogger(PriceClientImpl.class); + /** * Makes a simple HTTP Get request to the Price microservice. * @@ -49,12 +57,26 @@ public class PriceClientImpl implements PriceClient { .build(); try { + LOGGER.info("Sending request to fetch price info"); var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString()); + logResponse(httpResponse); return httpResponse.body(); } catch (IOException | InterruptedException e) { - e.printStackTrace(); + LOGGER.error("Failure occurred while getting price info", e); } return null; } + + private void logResponse(HttpResponse httpResponse) { + if (isSuccessResponse(httpResponse.statusCode())) { + LOGGER.info("Price info received successfully"); + } else { + LOGGER.warn("Price info request failed"); + } + } + + private boolean isSuccessResponse(int responseCode) { + return responseCode >= 200 && responseCode <= 299; + } } diff --git a/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java index b1f6dd3f7..a96ef4f41 100644 --- a/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java +++ b/api-gateway/image-microservice/src/main/java/com/iluwatar/image/microservice/ImageController.java @@ -23,15 +23,20 @@ package com.iluwatar.image.microservice; +import static org.slf4j.LoggerFactory.getLogger; + +import org.slf4j.Logger; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; + /** * Exposes the Image microservice's endpoints. */ @RestController public class ImageController { + private static final Logger LOGGER = getLogger(ImageController.class); /** * An endpoint for a user to retrieve an image path. @@ -40,6 +45,7 @@ public class ImageController { */ @RequestMapping(value = "/image-path", method = RequestMethod.GET) public String getImagePath() { + LOGGER.info("Successfully found image path"); return "/product-image.png"; } } diff --git a/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java index cf2f5eb4f..dbcd59952 100644 --- a/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java +++ b/api-gateway/price-microservice/src/main/java/com/iluwatar/price/microservice/PriceController.java @@ -23,15 +23,20 @@ package com.iluwatar.price.microservice; +import static org.slf4j.LoggerFactory.getLogger; + +import org.slf4j.Logger; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; + /** * Exposes the Price microservice's endpoints. */ @RestController public class PriceController { + private static final Logger LOGGER = getLogger(PriceController.class); /** * An endpoint for a user to retrieve a product's price. @@ -40,6 +45,7 @@ public class PriceController { */ @RequestMapping(value = "/price", method = RequestMethod.GET) public String getPrice() { + LOGGER.info("Successfully found price info"); return "20"; } } From 8305e9365dd52740a9e7afe9129c470411cd1296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 9 Aug 2020 21:49:00 +0300 Subject: [PATCH 212/285] Fix typos --- private-class-data/README.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/private-class-data/README.md b/private-class-data/README.md index a105cac34..2e599a78d 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -9,27 +9,31 @@ tags: --- ## Intent -Private Class Data design pattern seeks to reduce exposure of -attributes by limiting their visibility. It reduces the number of class -attributes by encapsulating them in single Data object. +Private Class Data design pattern seeks to reduce exposure of attributes by limiting their +visibility. It reduces the number of class attributes by encapsulating them in single Data object. ## Explanation Real world example -> Imagine you are cooking a stew for your family for dinner. You want to prevent your family members from consuming the stew by tasting it while you are cooking, otherwise there will be no more stew for dinner later. +> Imagine you are cooking a stew for your family for dinner. You want to prevent your family members +> from consuming the stew by tasting it while you are cooking, otherwise there will be no more stew +> for dinner later. In plain words -> Private class data pattern prevent manipulation of data that is meant to be immutable by separating the data from methods that use it into a class that maintains the data state. +> Private class data pattern prevents manipulation of data that is meant to be immutable by +> separating the data from the methods that use it into a class that maintains the data state. Wikipedia says -> Private class data is a design pattern in computer programming used to encapsulate class attributes and their manipulation. +> Private class data is a design pattern in computer programming used to encapsulate class +> attributes and their manipulation. **Programmatic Example** -Taking our stew example from above. First we have a `Stew` class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. +Taking our stew example from above. First we have a `Stew` class where its data is not protected by +private class data, making the stew's ingredient mutable to class methods. ``` public class Stew { @@ -66,7 +70,9 @@ public class Stew { } ``` -Now, we have `ImmutableStew` class, where its data is protected by `StewData` class. Now, the methods in are unable to manipulate the data of the `ImmutableStew` class. +Now, we have `ImmutableStew` class, where its data is protected by `StewData` class. Now, the +methods in are unable to manipulate the data of the `ImmutableStew` class. + ``` public class StewData { private final int numPotatoes; @@ -106,7 +112,8 @@ public class ImmutableStew { } ``` -Let's try creating some instance of each class and calling their methods +Let's try creating an instance of each class and call their methods: + ``` var stew = new Stew(1, 2, 3, 4); stew.mix(); // Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers From 5eb9b98e784ba9f5a37b342e804cc5a361927eb0 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 00:24:20 +0530 Subject: [PATCH 213/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 0b7f209c2..5c35e8734 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -76,7 +76,7 @@ public class Hotel { } ``` -This class has two methods, one for booking and cancelling a room respectively. +The `Hotel` class has two methods, one for booking and cancelling a room respectively. Each one of them handles a single transaction in the system, making `Hotel` implement the Transaction Script pattern. ``` public void bookRoom(int roomNumber); From 94c131f7e929ab775dbcc7f3c138f0be199063a7 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 00:24:33 +0530 Subject: [PATCH 214/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 5c35e8734..b3740862b 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -13,8 +13,7 @@ Transaction Script organizes business logic by procedures where each procedure h ## Explanation Real world example -> Your need is to be able to book a hotel room and also be able to cancel that booking. -> +> You need to create a hotel room booking system. Since the requirements are quite simple we intend to use the Transaction Script pattern here. In plain words > All logic related to booking a hotel room like checking room availability, From 45e416928d04e95fdbef4a63f3009393945fe5ad Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 00:24:44 +0530 Subject: [PATCH 215/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index b3740862b..c8e934a1b 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -23,7 +23,7 @@ In plain words Programmatic example -The Hotel class takes care of booking and cancelling a room in a hotel. +The `Hotel` class takes care of booking and cancelling room reservations. ```java public class Hotel { From 7450456dae2c94246cca9c25b5aad155ecda1b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 9 Aug 2020 21:54:54 +0300 Subject: [PATCH 216/285] Add syntax highlighting --- private-class-data/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/private-class-data/README.md b/private-class-data/README.md index 2e599a78d..d4788d2dd 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -35,7 +35,7 @@ Wikipedia says Taking our stew example from above. First we have a `Stew` class where its data is not protected by private class data, making the stew's ingredient mutable to class methods. -``` +```java public class Stew { private static final Logger LOGGER = LoggerFactory.getLogger(Stew.class); private int numPotatoes; @@ -73,7 +73,7 @@ public class Stew { Now, we have `ImmutableStew` class, where its data is protected by `StewData` class. Now, the methods in are unable to manipulate the data of the `ImmutableStew` class. -``` +```java public class StewData { private final int numPotatoes; private final int numCarrots; @@ -114,7 +114,7 @@ public class ImmutableStew { Let's try creating an instance of each class and call their methods: -``` +```java var stew = new Stew(1, 2, 3, 4); stew.mix(); // Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers stew.taste(); // Tasting the stew From 6cef98d41e440dd002b3f6152e8f5ee07183036e Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 00:25:01 +0530 Subject: [PATCH 217/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index c8e934a1b..4315c0475 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -93,8 +93,7 @@ if booked then calculates the refund amount and updates the database using the D ![alt text](./etc/transaction-script.png "Transaction script model") ## Applicability -Use the transaction script model when the application has only a small amount of logic and that -logic won't be extended in the future. +Use the Transaction Script pattern when the application has only a small amount of logic and that logic won't be extended in the future. ## Known uses From 31d753e59dfdad59a29b9992d706cb2987860984 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 00:25:43 +0530 Subject: [PATCH 218/285] Update transaction-script/Readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ilkka Seppälä --- transaction-script/Readme.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 4315c0475..1c1d789ec 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -16,10 +16,7 @@ Real world example > You need to create a hotel room booking system. Since the requirements are quite simple we intend to use the Transaction Script pattern here. In plain words -> All logic related to booking a hotel room like checking room availability, -> calculate rates and update the database is done inside a single transaction script. -> Similar procedure is also needed for cancelling a room booking and all -> that logic will be in another transaction script. +> Transaction Script organizes business logic into transactions that the system needs to carry out. Programmatic example From 87f3a4d95623476931716ed901b5a529a7f19b68 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 12:48:55 +0530 Subject: [PATCH 219/285] Delete module-info.java --- dao/src/main/java/module-info.java | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 dao/src/main/java/module-info.java diff --git a/dao/src/main/java/module-info.java b/dao/src/main/java/module-info.java deleted file mode 100644 index 08e4f662e..000000000 --- a/dao/src/main/java/module-info.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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. - */ - -module com.iluwatar.dao { - requires org.slf4j; - requires java.sql; - requires h2; - requires java.naming; -} \ No newline at end of file From 5441db658270247b0e326fd52265add87adafbfc Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 12:52:15 +0530 Subject: [PATCH 220/285] Update pom.xml --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 38d8e97db..9b3382795 100644 --- a/pom.xml +++ b/pom.xml @@ -376,10 +376,6 @@ org.apache.maven.plugins maven-surefire-plugin - - - -Xmx1024M ${argLine} - 3.0.0-M5 From f5c337981b06cf3a392f761097e4ccf6dde24575 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 12:52:37 +0530 Subject: [PATCH 221/285] Rename Readme.md to README.md --- transaction-script/{Readme.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename transaction-script/{Readme.md => README.md} (100%) diff --git a/transaction-script/Readme.md b/transaction-script/README.md similarity index 100% rename from transaction-script/Readme.md rename to transaction-script/README.md From c0edac0046a86ae108e5c9789a3e67c681b6e9f2 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 12:53:13 +0530 Subject: [PATCH 222/285] Rename TransactionScriptApp.java to App.java --- .../transactionscript/{TransactionScriptApp.java => App.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/{TransactionScriptApp.java => App.java} (100%) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java similarity index 100% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/TransactionScriptApp.java rename to transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java From 24126edd86295d0bbf94cc46090168027885f365 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 12:54:46 +0530 Subject: [PATCH 223/285] Update Hotel.java --- .../main/java/com/ashishtrivedi16/transactionscript/Hotel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index 8a756f99c..3a73c78ab 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory; public class Hotel { private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); - private HotelDaoImpl hotelDao; + private final HotelDaoImpl hotelDao; public Hotel(HotelDaoImpl hotelDao) { this.hotelDao = hotelDao; From 4c9cad547518c222cff329efb3d40331ba3a4599 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 13:01:12 +0530 Subject: [PATCH 224/285] #1321 Updated README --- transaction-script/Readme.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/transaction-script/Readme.md b/transaction-script/Readme.md index 87cd138f6..13ae9c48a 100644 --- a/transaction-script/Readme.md +++ b/transaction-script/Readme.md @@ -97,10 +97,6 @@ if booked then calculates the refund amount and updates the database using the D Use the transaction script model when the application has only a small amount of logic and that logic won't be extended in the future. - -## Known uses -* Revenue recognition in business systems. - ## Consequences * As the business logic gets more complicated, it gets progressively harder to keep the transaction script From 4008ae41b5b12567203322fc5f3a0e12af5c0d81 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 13:02:35 +0530 Subject: [PATCH 225/285] #1321 --- .../main/java/com/ashishtrivedi16/transactionscript/App.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java index e49e1d501..74818ac02 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java @@ -29,7 +29,7 @@ import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TransactionScriptApp { +public class App { private static final String H2_DB_URL = "jdbc:h2:~/test"; private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); From 5527cf423438037ff5a0b370b0cbb04a2739ed34 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 13:06:46 +0530 Subject: [PATCH 226/285] #1321 Renamed main class --- transaction-script/README.md | 2 +- transaction-script/etc/transaction-script.urm.puml | 2 +- transaction-script/pom.xml | 2 +- .../main/java/com/ashishtrivedi16/transactionscript/App.java | 2 +- .../main/java/com/ashishtrivedi16/transactionscript/Hotel.java | 2 +- .../java/com/ashishtrivedi16/transactionscript/AppTest.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/transaction-script/README.md b/transaction-script/README.md index 05a428667..7d784101b 100644 --- a/transaction-script/README.md +++ b/transaction-script/README.md @@ -24,7 +24,7 @@ The `Hotel` class takes care of booking and cancelling room reservations. ```java public class Hotel { - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private HotelDaoImpl hotelDao; diff --git a/transaction-script/etc/transaction-script.urm.puml b/transaction-script/etc/transaction-script.urm.puml index 4a5bf02f8..e8d172377 100644 --- a/transaction-script/etc/transaction-script.urm.puml +++ b/transaction-script/etc/transaction-script.urm.puml @@ -1,6 +1,6 @@ @startuml package com.ashishtrivedi16.transaction-script { - class TransactionScriptApp { + class App { - H2_DB_URL : String {static} - LOGGER : Logger {static} - addRooms(hotelDaoImpl : HotelDaoImpl) {static} diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index f51bf36cf..e53bb4b4a 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -60,7 +60,7 @@ - com.ashishtrivedi16.transactionscript.TransactionScriptApp + com.ashishtrivedi16.transactionscript.App diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java index 74818ac02..473a2f03f 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory; public class App { private static final String H2_DB_URL = "jdbc:h2:~/test"; - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); /** * Program entry point. diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index 3a73c78ab..c487f4ce5 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -28,7 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Hotel { - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionScriptApp.class); + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private final HotelDaoImpl hotelDao; diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java index a4c22739d..755a95653 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java @@ -31,6 +31,6 @@ import org.junit.jupiter.api.Test; public class AppTest { @Test public void test() throws Exception { - TransactionScriptApp.main(new String[]{}); + App.main(new String[]{}); } } From 108532d8dd8caf0c309c676e6ecd50085b18b77a Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 13:12:12 +0530 Subject: [PATCH 227/285] #1321 --- .../java/com/ashishtrivedi16/transactionscript/Hotel.java | 1 - .../com/ashishtrivedi16/transactionscript/HotelDaoImpl.java | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java index c487f4ce5..be9000af5 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java @@ -23,7 +23,6 @@ package com.ashishtrivedi16.transactionscript; -import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java index e95363fb5..d1f90a98b 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java @@ -33,8 +33,11 @@ import java.util.function.Consumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class HotelDaoImpl implements HotelDao { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private final DataSource dataSource; @@ -67,7 +70,7 @@ public class HotelDaoImpl implements HotelDao { try { mutedClose(connection, statement, resultSet); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error(e.getMessage()); } }); } catch (Exception e) { From 75b10ed657bf03595133fc0f4f9be09947a98c2f Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Mon, 10 Aug 2020 13:21:24 +0530 Subject: [PATCH 228/285] #1321 --- .../transactionscript/App.java | 2 +- .../transactionscript/HotelDaoImpl.java | 20 ++++----- .../transactionscript/SqlException.java | 43 ------------------- .../transactionscript/HotelTest.java | 2 +- 4 files changed, 12 insertions(+), 55 deletions(-) delete mode 100644 transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java index 473a2f03f..576458e0b 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java @@ -88,7 +88,7 @@ public class App { var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); } catch (Exception e) { - throw new SqlException(e.getMessage(), e); + throw new Exception(e.getMessage(), e); } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java index d1f90a98b..e64b64699 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java @@ -74,7 +74,7 @@ public class HotelDaoImpl implements HotelDao { } }); } catch (Exception e) { - throw new SqlException(e.getMessage(), e); + throw new Exception(e.getMessage(), e); } } @@ -92,8 +92,8 @@ public class HotelDaoImpl implements HotelDao { } else { return Optional.empty(); } - } catch (Exception ex) { - throw new SqlException(ex.getMessage(), ex); + } catch (Exception e) { + throw new Exception(e.getMessage(), e); } finally { if (resultSet != null) { resultSet.close(); @@ -115,8 +115,8 @@ public class HotelDaoImpl implements HotelDao { statement.setBoolean(4, room.isBooked()); statement.execute(); return true; - } catch (Exception ex) { - throw new SqlException(ex.getMessage(), ex); + } catch (Exception e) { + throw new Exception(e.getMessage(), e); } } @@ -132,8 +132,8 @@ public class HotelDaoImpl implements HotelDao { statement.setBoolean(3, room.isBooked()); statement.setInt(4, room.getId()); return statement.executeUpdate() > 0; - } catch (Exception ex) { - throw new SqlException(ex.getMessage(), ex); + } catch (Exception e) { + throw new Exception(e.getMessage(), e); } } @@ -143,8 +143,8 @@ public class HotelDaoImpl implements HotelDao { var statement = connection.prepareStatement("DELETE FROM ROOMS WHERE ID = ?")) { statement.setInt(1, room.getId()); return statement.executeUpdate() > 0; - } catch (Exception ex) { - throw new SqlException(ex.getMessage(), ex); + } catch (Exception e) { + throw new Exception(e.getMessage(), e); } } @@ -159,7 +159,7 @@ public class HotelDaoImpl implements HotelDao { statement.close(); connection.close(); } catch (Exception e) { - throw new SqlException(e.getMessage(), e); + throw new Exception(e.getMessage(), e); } } diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java deleted file mode 100644 index 369eb259d..000000000 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/SqlException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.ashishtrivedi16.transactionscript; - -/** - * Custom exception. - */ -public class SqlException extends Exception { - - private static final long serialVersionUID = 1L; - - public SqlException() { - } - - public SqlException(String message) { - super(message); - } - - public SqlException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java index 86f4605b3..26bf4b5cd 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java +++ b/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java @@ -114,7 +114,7 @@ public class HotelTest { var statement = connection.createStatement()) { statement.execute(RoomSchemaSql.CREATE_SCHEMA_SQL); } catch (Exception e) { - throw new SqlException(e.getMessage(), e); + throw new Exception(e.getMessage(), e); } } From 10815b646991003bd9e6980114af088daae2775c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 10 Aug 2020 16:05:52 +0300 Subject: [PATCH 229/285] Fix tags --- aggregator-microservices/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md index 36cbad33d..b1bd5d762 100644 --- a/aggregator-microservices/README.md +++ b/aggregator-microservices/README.md @@ -6,6 +6,8 @@ permalink: /patterns/aggregator-microservices/ categories: Architectural tags: - Cloud distributed +- Decoupling +- Microservices --- ## Intent From 04a2be0c9963932c283c8bc29fdb5e332ce94235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 10 Aug 2020 16:25:06 +0300 Subject: [PATCH 230/285] Update readme --- api-gateway/README.md | 59 +++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/api-gateway/README.md b/api-gateway/README.md index 0d67b8d9b..66cdb20af 100644 --- a/api-gateway/README.md +++ b/api-gateway/README.md @@ -12,49 +12,53 @@ tags: ## Intent -Aggregate calls to microservices in a single location: the API Gateway. The user makes a single call to the API Gateway, -and the API Gateway then calls each relevant microservice. +Aggregate calls to microservices in a single location, the API Gateway. The user makes a single call +to the API Gateway, and the API Gateway then calls each relevant microservice. ## Explanation -With the Microservices pattern, a client may need data from multiple different microservices. If the client called each -microservice directly, that could contribute to longer load times, since the client would have to make a network request -for each microservice called. Moreover, having the client call each microservice directly ties the client to that -microservice - if the internal implementations of the microservices change (for example, if two microservices are -combined sometime in the future) or if the location (host and port) of a microservice changes, then every client that +With the Microservices pattern, a client may need data from multiple different microservices. If the +client called each microservice directly, that could contribute to longer load times, since the +client would have to make a network request for each microservice called. Moreover, having the +client call each microservice directly ties the client to that microservice - if the internal +implementations of the microservices change (for example, if two microservices are combined sometime +in the future) or if the location (host and port) of a microservice changes, then every client that makes use of those microservices must be updated. -The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway pattern, an additional -entity (the API Gateway) is placed between the client and the microservices. The job of the API Gateway is to aggregate -the calls to the microservices. Rather than the client calling each microservice individually, the client calls the -API Gateway a single time. The API Gateway then calls each of the microservices that the client needs. +The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway +pattern, an additional entity (the API Gateway) is placed between the client and the microservices. +The job of the API Gateway is to aggregate the calls to the microservices. Rather than the client +calling each microservice individually, the client calls the API Gateway a single time. The API +Gateway then calls each of the microservices that the client needs. Real world example -> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system the API Gateway makes -calls to the Image and Price microservices. +> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system +> the API Gateway makes calls to the Image and Price microservices. In plain words -> For a system implemented using microservices architecture, API Gateway is the single entry point that aggregates the -calls to the individual microservices. +> For a system implemented using microservices architecture, API Gateway is the single entry point +> that aggregates the calls to the individual microservices. Wikipedia says -> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling and security -policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often -includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also -provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to -support authentication, authorization, security, audit and regulatory compliance. +> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling +> and security policies, passes requests to the back-end service and then passes the response back +> to the requester. A gateway often includes a transformation engine to orchestrate and modify the +> requests and responses on the fly. A gateway can also provide functionality such as collecting +> analytics data and providing caching. The gateway can provide functionality to support +> authentication, authorization, security, audit and regulatory compliance. **Programmatic Example** -This implementation shows what the API Gateway pattern could look like for an e-commerce site. The `ApiGateway` makes -calls to the Image and Price microservices using the `ImageClientImpl` and `PriceClientImpl` respectively. Customers -viewing the site on a desktop device can see both price information and an image of a product, so the `ApiGateway` calls -both of the microservices and aggregates the data in the `DesktopProduct` model. However, mobile users only see price -information; they do not see a product image. For mobile users, the `ApiGateway` only retrieves price information, which -it uses to populate the `MobileProduct`. +This implementation shows what the API Gateway pattern could look like for an e-commerce site. The +`ApiGateway` makes calls to the Image and Price microservices using the `ImageClientImpl` and +`PriceClientImpl` respectively. Customers viewing the site on a desktop device can see both price +information and an image of a product, so the `ApiGateway` calls both of the microservices and +aggregates the data in the `DesktopProduct` model. However, mobile users only see price information; +they do not see a product image. For mobile users, the `ApiGateway` only retrieves price +information, which it uses to populate the `MobileProduct`. Here's the Image microservice implementation. @@ -64,7 +68,6 @@ public interface ImageClient { } public class ImageClientImpl implements ImageClient { - @Override public String getImagePath() { var httpClient = HttpClient.newHttpClient(); @@ -114,7 +117,7 @@ public class PriceClientImpl implements PriceClient { } ``` -And here we can see how API Gateway maps the requests to the microservices. +Here we can see how API Gateway maps the requests to the microservices. ```java public class ApiGateway { From e99bcf772bd830d02221f1eaa34db535b0da4372 Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Tue, 11 Aug 2020 00:21:46 +0530 Subject: [PATCH 231/285] #1321 Added comments about TS --- .../transactionscript/App.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java index 576458e0b..98762520d 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ b/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java @@ -29,6 +29,20 @@ import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * Transaction Script (TS) is one of the simplest domain logic pattern. + * It needs less work to implement than other domain logic patterns and therefore + * it’s perfect fit for smaller applications that don't need big architecture behind them. + * + *

In this example we will use the TS pattern to implement booking and cancellation + * methods for a Hotel management App. The main method will initialise an instance of + * {@link Hotel} and add rooms to it. After that it will book and cancel a couple of rooms + * and that will be printed by the logger.

+ * + *

The thing we have to note here is that all the operations related to booking or cancelling + * a room like checking the database if the room exists, checking the booking status or the + * room, calculating refund price are all clubbed inside a single transaction script method.

+ */ public class App { private static final String H2_DB_URL = "jdbc:h2:~/test"; @@ -36,7 +50,8 @@ public class App { /** * Program entry point. - * + * Initialises an instance of Hotel and adds rooms to it. + * Carries out booking and cancel booking transactions. * @param args command line arguments * @throws Exception if any error occurs */ @@ -47,12 +62,15 @@ public class App { createSchema(dataSource); final var dao = new HotelDaoImpl(dataSource); + // Add rooms addRooms(dao); + // Print room booking status getRoomStatus(dao); var hotel = new Hotel(dao); + // Book rooms hotel.bookRoom(1); hotel.bookRoom(2); hotel.bookRoom(3); @@ -60,6 +78,7 @@ public class App { hotel.bookRoom(5); hotel.bookRoom(6); + // Cancel booking for a few rooms hotel.cancelRoomBooking(1); hotel.cancelRoomBooking(3); hotel.cancelRoomBooking(5); From 3c07a42e9d8d5ac2e38e25a85eb9f3349f271d9f Mon Sep 17 00:00:00 2001 From: Ashish Trivedi Date: Tue, 11 Aug 2020 00:23:00 +0530 Subject: [PATCH 232/285] #1321 Updated UML diagram --- transaction-script/etc/transaction-script.png | Bin 73666 -> 66480 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/transaction-script/etc/transaction-script.png b/transaction-script/etc/transaction-script.png index f3561f84db3661cff40d2624c47b512b0075fea1..6d0cffb6a55170dbd710f528ddf5fd95b89757c1 100644 GIT binary patch literal 66480 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]}MK;#%=!jm}b^t!DS(p2a*I^M5!#^f!%y^aJ* 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 QQM>EQODjv2Nf-tE5A9LpApigX literal 73666 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

KG$TPq}zSN=T>~v>;V?kB()7t?0 ze{F1>kgGOjm_6xaBoA`r6kDCwYx~`h`9&Yu0?3Wy!FJqd&d1p)6cHMcsjuRu*d{Yx zv0#>8TDFtI2D*#gxtR~*#Nz>L<&kOke#+W-H30yt8`NahmzmLQkyOLYq8_I;%GRnK zPEX3?c<7Ei`voFwbUT#FL&438YBLglcXZ~RI+EKyc4ltWKT07v4)zQ(; z2%A_5A^lv9rAC^)kzduYFbflk5Gr5`^}m3Ed2^`PwnlNxWN6Nuxs-WTfnl77Sb@e5@R>3MujBcI%stcJp2x&jDYzj`8L^n@taQ6t2OA`#cHLW4yV1iA6s9E;k&Y7MT(7W{^jOP z?>5E`xCkC9NKF+PiG$&vjKv;-bVmqc_1XtRlI6Qxiy)+DQ@?x9Vq6plLkqtS*utkY z$@C$h(^aZ>?X>oA(;s~Cg<18sit=$WXNB| z=SeJ%WT_pV#ys9{&tV4xLd1aTeo7dt8O3^d0Mk8Z)Vz7A6G0wdyF%Esqs2>hBweIj zIkJnx zsPzvMViu`+nmQh+S&rZCel0yja%Zi~KbpxN?WrU1flw}vsKQv}(F63)2c(aw0oBpq z(AS!oZCbTIvbr6vbVNVpQOiR|7hZY{)TSK~=6HC3a@Eth1vM0g=RyY|6v&VP=>9*x z?9w~{D#+y!9#Bm7|^6_2E zWcA$f=v@e8yaStyhFx&guJxYKLUIyTnA0gBlRwL>x+l5bg25&*rae|x+o8y)%AxW} z`|alR&lvW(-Ry8_Uq5sLsSs4W$FCIMjHqAAULXDcsrswfaM|*u%dANO;U_Y}=n-o< zW_@DgNb%C%7vYn(653bIYcsx3FvQ9TbpM()yC>4t(VwCLiso=Bf}I_MCnjI(cY@A% z7q@FNk1{n!0?Su)b+Wn~NM-Xknp&`DQ)}6_{s`}9LIc2YWVN06-4`tP>u9HiRQ3AD zz>C!Y{i06N3i9|m|Nc6(YqWRG*NAdKMSPdHG2=COoa(s8gNulb5Mq#e$;kA-J#mJ% z1S8M(U*B}Pu_}--8}JI#SaCtq#b;=`-l0Hba{UvrwSe=u>EpDjeyW4vP~>(LP}z%F zz=-_$cI@V+_P%H|?d!yOu(*Oh?qg&WQ-Wxa4^=J2F$Fj-3a;z?-WN+Fp}Gbs_q`O1 zJTy8JD{Q*E{0?qNtwE1|3a?00E~?ft3<0}z^{b&{V8cJ>X+3JW=Rl!ZbfB#TW94Dg z0!-YD4cP|h%vCHL)YNQGo;+sXVQeXZhICwmR9&w`)n?t}rBleCw+m6a3x$g66`Nx`sbWAjC7^QoZNb zYgsiN*wD4Q{k2E6Xya8)VZ*Qi?Sco?wtX(DP8pMs*-$B0)vsDQ{_uC|4Pfvab&#Ds z;W&-mHE5#Jk;#YFVJxJY)OAQfArfQ>rGd0~JrkN;Fum)tg zH-9_shhK%^t9C>(qNi0fxyO1-=(J@2xZeSKO+39il8%9n{#^ z2jwl+mJI_e@>_2&uUc76mtyr!_gA379Z}5zk#kPdXOzwWS9f-4pwe_WrxZ+v3g0I- zcylpYc5SH9uiVcocLMyZ64C&Hx&p$#50hpbu7l4}#Zw^>Gx;_u z{zo_f$Ih1T>p!EBw!du-y6_QHF@hd#n=eQ3+_65ljHJg*Vpr2=1dKK#F1%qKcxtrG zFDU}G2M2yr_rFP9*Yv$ej*k{1t|`e<^MVz*gotu1^aYcN%2J%n*YPw3fu@uE{Jgy2 zaXT5nemjo#lsDpVR+=z*B5Da+91gs4^K&g5FIe*Yu5gE0SItT0uJ!FPoL{T1N53l0 zB6{qUYZ+c(kd4rA6bH?iYzw$Vau~}6n>wyn)Fx4bo>;oK0_T^OImb9+@wV?`DlnFPT#6B?3rt2)XAK&NU5VA{^J;-ztqLs$C|RR7hN( z^GpccZHNB!{)M-AKMiPEVN6F!Q|@N8ws#+u1*JECv|H7|gEi5NvAng4zq5W-&VUfk`gaggN@=zipy+hP^ z$``IKu0jm(pC>@}X!e%_Bo+jtzijc&YaZ>o=ie_K3cS1*^U&wt8SJ)nxjZDNFFGGP z1agXBiJF|`0);rzT(nY?Ppv74tq$g~ksrWgJe(7UVMrTXtX4}s)fGK3K01#4jm_H6 zj7 zGwE9bi!AoX2jj#(%Ib})iUeEr?8kwJ8)-}U4Q2aYZ02SxhS`z$GpU|3OB;H`Gk>CqgYoj;T#0}dW82;j45HF@&t zh()v57`8DPwZS02&g2%*F5}-((QP>9jKOo}_`j^E0Ze-0k!y2_wJ^kRnelcJHjDU2YxulLGvyPci|6^vm*d z%~44Nk`l2?EVa$)Rk`;(b>9P$SyqjeP8*cH_;ABDUct}M{{dq9NRZUjW}&ZV_R~c{ za;EwmS|lB_tuH6H2e_(i;^}oEk_c9g1(62kZY^~xa@BT`f^uVYSDp*Qp;_2Rr6ckl zx$CC4@U5%+xl3h7*Wl-mRy$+W0K}$z2{P(RNy}Fz(d`z+mJ;o^LnzY8H~tS@Zy8Y4 z)`bgiML_{UrBe|FY3T;(?(UK<=?|`kNc^ob%rM-Su-TYt1>= z$Y(rbEI8fq(I0KM5TAf6V($1ukKETsBP~TG!Sj`K-GC(^?!Z>-i>cb}=uCT1ux`I- ze*EU zNO_tbLoqdn?WQ;M`o}nRwmmI9Bq*GYBur9Q4Z)yH#|Vsp_-8<)`)$bQkS|=9_-5yX z8=j}Vbia^Rzl|MmYE90@i+ix?&6q$nahbX*0Vz!EE*`Hn-s_2t!h+~7+-jWzV?alc-w^3eKkuva|wIx~b zWhrukH|Qu>?%3V#_yS`u=S`*rR`yh9f?0GSj)dy+nNB;0a*p&%Iaa-%?-VNNCA`fX zDT#Ti%sis{eg|*Fm(Ae5a{@<;j!?*hOG4f^$9@Q8oTqnYRA1M$E^NV)vJUBQwFOQ1 zeJHXp$5({Mx0o1A=7}SL75pj7^NKgJVpT(-0=WHWFL#fW(Nrjh-&xn8HRou7T*JJM zdIzxDH%9Xve($kF3KYzmpp2sk*D=)Y_Z}S3bWr(+yx>*oy?#x-g~IZyB++-3_v(#! z!>@aLIM9%3c=Ka6zR}U8PPi~4y^~5(M7dwW5>QkZV(;wn9tN9Nn9oYvz9_Lw@&zD-+>R~e z5*8S3b0<6+ONQn5bCT1p8+*TX!n+#no_G{i9xHMF@b4z~Soy0f|A}l5OVo21t|(7b z;ao-&tqKpSga6dX@XkV}51*<0kt(D~uV>!DZV?hsKvF)OBVz^4%0ryrbZeD7)+T55 zN%*aI$G>lkWOTd!4WJ*Uo>RXet5nNMn7J3w1bTcEq8@xeejgL+QyfB`#dsy6c1Aes zT&d{h4d(=UtYg7Hts3e-ai4`+dz=FtCk^9wyPv)r)~C(d^R8PyWwoP(2ZVGK6f6uz z_gS;_I{D?N1^QV0mX$s!iyF&^t%Dgup#RqIO6vPzheTMM>HQGh)pvg8nRR;t>Tqc3 zczmN6f2i!XGBM2`l9-NJ!fWv$H{WmRmZ<1mrH?fKCrZFJ;R`CW6vRAWa>)%GV(DGb zL`PKlrBd`g;kpdYALh0ms^YmaWTJJl?1xo^%iw2R-U>Wp z^R_4i$Yy`;pIVPT^IXsw1hDw*X1Y<&p%Am}j=mHjXk9QzuaI_y3Cths{&-{_K|M^O z|1Q8|y~tT@w5Z;@e*WFWQvog*yYnIZw@7#XTP#jJYcXA``TU3#A6hxv!*958rNxT` zoQR9<%4s$!h9~T7k!n({j5@!60=4;{Jo(m#0y<_Gh^tLvGK;FYhXs9v#)TupDE1h? zV-h{-`h3vBeIt*>2Ne_kRFA|#O^=|G;|voR@%bQL1uT}j zk;da5KAa5m>h<+SFDTTO#Dn(ZPO%QBW)mKG+^Qk-llRo~aB+Vc%I?Sj0OEmsrz$oB zHE3F;;su+hl{1q)AAKU2DCE8KWgG6bjc)2Q2wAH;>5P^rvb}CSh;{dMLZ0R*8$8Cc8`@)H0P%gk*a+o zG|eE8(>o$2!2bRaF%wyTMFK>i_X8i2X2ucA+K1Wt3yS&qCc49D2GgqfDX6HN!D5mX zMipPkV-<@tdk`UIUXs&8VWzPHwKTCf19cBArzf{d3jPecbCks{iF-#(6-~!eo-w&j zi%{SAWz?iu+EG3F%+12$tbABX~T0uE-&y9S!stNYMgM^CunfsTRQ$#Tf>x*M>}oD0ej_x4+I1tj@V5g;CP@DY;U<9Zn3%yjnRR<+?o zw~x73P^&9iC*GPvi(I_;@|SI^7uO=pJ7pClwiyUd0Zh5UT;9S(+!Y9&U%uQjbL?7}g# z9O5Ulw^^ATQk|UXx!P8BFhNfLh|3wrvK8LnjM+SV0j>y~FD9lK106M=Y6a$0&+(p_ zH&T%)wP(ja?@dkbjW+&uS$4!{OAFd?om@gUYfw{xO=w+yWlK^wy%5QvVkqUIIOXV$ zDxnRn(r)snH_1Q1A>$+y6I+v|kWGvQ!t!$+S}0vieBJ76q| zczFb$jKzieT-ePfOy!O(pL#vBS_$+I3QFzD835cXYGWy(`EB&dqX|izgs^N`K|#~W z;@b|^&J_AaU}XbP14%X$4l&KAKyIA zYeyQ?8MCi<5MkH*{l`@;^~8`@yaOP_#nJjp{XNV_yRhzVAYld>KH>4)AdbH3nM4ef zV!dQit+0!w`7_2(0%OfHDxNI>ok$e(V9vw8kvx2#(H@`rsXzf~y7#77N0>W6a3`F+ z@Dy%-5Xl!NT7fp7@sg?33BEM$NvKRJ;%twX8&kEb2?@pEfm(;yy|Ax(C4NZV?{gLR z0XN9E6_4niv_CFX%jx((>{ER5{z+$&RQiYkDQxl6@&|;=$_mSuf5XB2jLs`iaBy(d zW&DsPBfoj{UfZVR;fxlT(n^Eknr!LxMFfjMrf=@uEPoJ1kuC=YhTHvsVh`RP?}sXF zo4qO<)Xk^Rh+^$TN6!9 zKKT&LN?w`xax?1p{=|2|zI+|h8Nq-m!RMff{W;02QF)}-{OankXD}e3|NQw|DcNY3 zSqHzqeEtwjXUayA!J;=zgcF`6iO1s(EX)Ij4bx8)ht*6skC)hWDp2CJ|L1Mr5w)P` z&7g=&i{d9R`@oW++2Ko4PkiD@4|Eq`Xe5V5&5S48W5quirn&v^t5bH+&R9}PHQU$? z^YyKYth9Y?D}{^vXd5dD5TW0haF$&svkS_M{hsK8mCt` zpOFs1YWOcR4}^;bXQMhiGVLD=Jt9f?`t+DW{856lvn5Zu(g9bX*hzHawMWtjR2;pu zUm}$<2L*^>vNW3hVzqXhf%XPoTg6z{u-k4OT>VVrXHPf0Q%ohLxN)I|_&7HhSSrfd zZ(8jC^E!M`W83yn$U@+j%}tlzvse)sFSd=@Cjz|MZtdr13ga3Ae4H+$UYbK)U7sgS zwyy|z#=kIt*5Fv_1wB$)g9@n%FVKMW0#k7xbn*sY>Z2`HSMf~JB84T)q1OIa0I?tt zKxl_aMs~u(K`P9?IB+3kVB@5=f_I5+g{O-zYkBN*$wWv1+a%dG`;=_y6I0I$9VNpT zvWF#8wRVqlL5G*?1SsHYUZjsp#LCrTqF7{Hr(T5 zgB66TVn=sSNB5_oi&u$sf7U&FVXal3`wZ`e2BZ90e0VQtx{eU{zaMU?a*CfsQ#$p?o!pzdGhd!(r{ND7DRDPgiUL8-58oR!6FAKSk zXCM9JUr*j!-16D}hUS>hKbzSr?$nrSU6Ah85*G zf03?Aig?`nePd}stqTZw2ML)4X^3%F^FQt}>o+BfJ$jTanL8Tf zgOpKHSb!LNKw08z8E{mNHL8qkvtW9gjWWJcVPcm(;!KJ_48A;MFTb6n5z%)J25C_0 zTPf!D+Jv8E&!UO5>bc>oky#eJQE;EmKnHY`CN0r00i-4@DWZq$nOlf$~ z_Fb6jI7scCq65QHqb%@ewHn!=?U+J^-+8YIr&>Wx%$7dic&y?a(r%e*j~V!HT^UG{ z?gJxg-g26a;_GUp%A={gW=lbX;&4~c;?xLb?G%kQ&5S*()cOH%u%n#7$@wZ47R;H| zImsZ7E?$nRy`Q+VE|q@Bj0-QCER_IJDAZeaLsU?38}tmc1vv#qf>E?<5Bi1o4e-ei zp_NE)AadR1XnBt#wE#f^I@il(BrqM_IPA2D2H#gJKvDeJ3|xigqvzcEM7F_NyKqJL z8!f+}=>p&>TaK&hE~)DFVD;|ic54297~wF^j(Pe1Il<=Uz@j_@MY4v5LujRn z_U93%f}n!5DKtxxX1y*fx?cu*119-R@2W|#P6C@h5HsSvUHpSn9^KEdklHg;91=UD^g!bArY%-zyO=#N(7mH z^hlQfu6HSGuDqzVa-1bH+2SW(l@GStV8YLv^p^zM$aq94;?DQ~ z4cfj)_h9*)?RLAp%);t9U^<|Rg3bUjHnaqMJ?=!{mWjN_!n)!7l*+|JKFAZR%rzMy z4%md(a#QM#ivnc987BhWR4>~3^pHA_o12`{N?}-0oyOO59jOID|ZE&|vMH4Ko4IZw z*sg;4hd3Z@FEMh!Mcl7u=~AsQ!IJkVVbDz-BKn=8{s6&Xl1R{~c~bvZ+a5M$W_LBI9^+`=N~K2J7JL5p}#7og8%$yrQ*?*E>y z$#6gMxH+usmtsgWZf>L^V8-Ju8qx#M5JS~xJf@Z}dKNzUmXpk5g>Pf~tNdSE8=4(6 zgcZYwfws(#O)g_)9lWIe6W+n*KHHY6CJWDKsR+kH+%uI`E|X~vKMkA^|LAX$5`ZqY zGktM@C*SpCe}&?>=l3l&_%D$2;)G=sU$raE_9rogjDI`@u*VMg72I{yosRAZ)O0@f z@N8gk9GE#X?(r3;*aN6UquoAf@DC6!QF#8-!63^UK^Ggp>Rg zx9N&)yaPBubLt0}&rDrLBG!vr9L$zVTa{+nmm)S~(a4jr6z8NR9y`31*%hV!DTEVv z;k9OUxZ;g~Q|yL=_uq$Sz)VO>*!B@F8P`!I*HEdLx53rqbnSq)w(yqCZpXm(qC{0b zX3ctI@oB09Ccks_t(+o`R2ZW49@d?$96|>TqGmO*AeMJJDPke>=7~AP&SUjV;xQFT z7#QH$5;o8b`$^n!p~)Tbx}s^t-M|U7mp3NUAot32KKSutgI@sJ?RmOB^r<}~<-FFe z(d#*w(9C2y`LWc4S1Dgf&q4`FezA(7CfHKp?LUFw0Fu6UXM?{}n^p-5Zx7*Xs+kiuSyD zzWCK|$VC^z$kW0nCe9A{!FywCUXb5dw;|WeqmUJX!uz;MNH$Q!L294w72|!UBR)2U zKW6r_ZD#D7*v*COB8$~d1YQW}nTZ0qHyqZG=MBw8ArI1=?f#^1Ky3UgJ+~5z!Zc6R z=sqwfLO(U^9wZ)EqJLOHUjq1L?|*jIIQXSGi5prCZmbL5m?1!ZAb`sRok59y;;@j9{z(Gj>a>be7;ht<5qhE`x+q{LTBB@8x70>bo1^t?X z3H*Lu;(une+<~R~LMtcHj>?rD9~eL}AmX5or>srd*xDcmb0YrrZ=? zKi&2@wwKpSFVJ~l^*lIg_wbGIUTX663G3=|)aWa0cbpAZq%!NsVN?vbXmVnh?Fq%h zF9ZF-g=b?I^m->c{WdM;iO=Kh8!uG_KrrI;NhgfxiSi%L9q!6}qrEDP1so|jCql|= zPAC2Q3Vb8i`(1B5=(@un@I7FBuPQ|s)is4dH%mhsrP|#?cSC8g;vX(-5a(4NlN0mE zH+kW6Re<30ND%{shS!E)Yl$dDZ{UK(hnV$OC{-y{f4gwbA}3X^CNf*C&~!WOBslOZ z%g8yl4Vay152qN^q>q!aVtM{dkHm-Iv2G;87zgalN31*?)YyM%ERiA5v$watP+abA z^b0gV$*{l&*aT9{87j)fj<23<^Jt50rn|B*%Vn!y?H?Uso=CGf#T1ShQ>YOxj#k-a z2;oyqOCfx25`RrpM5>8IX4WE^eeu~qypL;AaQx6J{IXr(@<=BB)ujNhn0)BBo%<{O zX5wP&O}w2qu4BFV*j{oArFoPhM8OVW`8do4Ctvw%p>_l#}6{-)7U3 zMTOu43=Rpx+&si(2J@Sno6Ebqpx-Ioa(C;8?q*mYnHc?Bytf90>=AmI7zh(vw0eQ5 zI}VODQjD46c>F`dZ&=nXw*~kqO-8yx#6(oW(7#bkRehN%)X1_}g#F24#7gD*=;D;B zP-QHk<{2uTES}KE$0)?&xT0v0Oj8ey=4kyv7S1JhW&#OlfIV9FOUY&4B6l9*H zp*ZOdtR^d$~ z`VyN>{;5)vk*!ZqE)$kpOo@rhphJ+%6Qh3V-Fn90SLh64#N6~@$tP!Pssx*DH8u_k zEz*+nOR}Gy7{7Y8QaWU{QlE=tF!N3Bg<69%lCkh)Y+2}W=;-o#*427Xeq^=?2B#zC*QLQS-^K`?=jci}o)C;T6PfNdyW?of6YBrI`qE=wsZ}s;Qm*VRCaP&x(=# zuf>~?#6Vz^T)xgqf49PEn7LK*f5m`=_MRgKAXQXd@wdaF)O2vx}CPjoikF>rRtl#_jDJ_^k z32{JgJK2!*S+3ug=HpGc_;}Lv%oVlZjNsHVeT-vgl0IXakz^Jwt03$VyPwJU{(b9` z%5S&5ZDUzcZhkM;VACHoT!vK;QKX}j%30zwm+XpA*({fY3r11mSzGc@+EA`P&+r=5 zHOv};rz3nq-f(V2Nyh2oXx!@Gmv_(^R=m)jIu<()7j`4Y9>hs)W^4FWK*VnNvt|*B z5}r-;;XuxiSJ|zi$!9z6%?Y23R8^3K)izo~6|E8>dz!XdnuwFff;Ih7oqm6vNMO3L zRvoV)arsb8i3{(RN2012j_dz(`&CDUxqWWpF4$zZf?+b0>32e!6M%90Q)s6rrY_eN z3}|?Z#9Frc+Dx5~cqI8~%67Sn10#xbYerr}gUU7tzBhNqi5PvuhR4ZhIMEM-BKG&u z(6wW}5P}lI@J+GK#p(JXV*cl{!^w=X!rf;mD49$8NLpTwk5Mv!SZq*;)MRds*6+^G zcXgT1h+5dXuKnJ(5x$NX)z+;aHE5Q(NLC-$xttvy`i-KqD7E-HByuPFVUs2?4e^HL z2ORg*!vVuFwTpSwwuYB__v>vbz;{eSh9weTd4lFWlAE0fATIKuW||8nN4ED&6P^-Nb;n7mANi9Vmd?Tz9=9&o3%X8D?)9rcnywdpBxSQs((+-rIP5aUp zs3*2JBo_I3IW`NWoJ=VO&>RaD`p}KO)WPwLhq^7MjhACLRb8uTpZc2E*Qvw;(4wuU zwkD4|fhAe1dWy@&-`U7EJyLG;{(ZAjsk)2=vm^9q4Zm@%SBrIqz>m|nFPMU{Ode+0 zSF#}%)>Z3(k6HVX4=9>stuKj;`ubqTF%TN<)pC*9T05l#7W%6z7w}D=WObdFV$pBa zQp+UGl_u#&7=C?=NK#%Ml9H*?V|lMOBeZ8$CG+I} zHBG;|T;w;b=XF!V%=8}0#;S_Mh84X;=kE_Hr;|yt$<2!@e!?v-g6tlQXY>9-(1V$w z_~X0^-B+EVK^+!UQ&N!wgY{tLr|=CZLW~f_AGY`Er9?;umNrD}KC}j3lr#l96EoU0 z&72xjISv?_&Ded!u^wdhcNkBfXg-pzL6at8DUUt>dVX@gc{P3%L;HB-8#}+xOGCx% zwY<--(xXcqB3plKRu`{)*cd9X6zotO<&l4zIT@DucDQ>SmLLl_C0@LrW&8UthKlpl z>y@oFwI%u`{aHNiF>VSCQrLf-8(QVo zJ!7QMTz^y$9PQH^zoix974Ijm29I$NggbE>CXqQ)b8OlhOGzxAr*G48axDKz+mqRHR1%@1a)9J>k)hA46u)^WUPY z^kE3Oyqw;ZLt3YhUpy#^31b&cpsW+MR;6D#oh{6evj4Ee4IehlqJ80*`<)NZXmLY9wjzFmXa;!58)6l>cj6_ibN2LXfE424OhH$*HjRH|vlr>`EL(AOyo)Df$gqotFqpehk(c=3%} z$*ngSif3{Z9JWdM(D9|Hw=q0ohPrhA;d@$s!0;CnzaE{2xIOXNRLtsZVwCq(=!_1_opZKi6hkEaS`S0ao0$NC)ImWM;p zxDE}Tq%58dlNn#C&moAEY81S)x;-#7+N9@i#q!^ZU3BynYFqMqbQ$q?|NQxw4n(?q zhxp9Tb1qpi($xta9bO9+b5-zqm_!enzbW^CHGENq22WC(9epS(hWJhK>xwik#89Lv z<6~0e#&WllLf)gD(flX1!tF@863a)1L)?Y~lZmKs6zuEDK~2G`KLBh(W=eqCpk802 zL4nGsrW5eGHD1ioOurS?3l{6w%cZg-h~iWl5`~bEkcEXsF8D|q5^nfj{}|ioe6HQf z;c^DfWV&H8B>m)}CyhSY@f$6KWY^<}@x{`m~JLAzIKpqt@D#ke?Cs zmc`-qF?L=5I~=0i@5@!gwmg$?rd~ffC`nh?Mu=eLtOr$vsrsM7y*Ki!LM=E5!s#r- zs@vlx_P^H_yxnNGOJghKs8!hTmGkpdss04`fQ@2p1&)n-jnv++kER)SuZzI5NDwT2 zO;AceSsDA7iipUY-%#UT`-hQ^oY~>+E4k~@$B!nX4Z|{@#4+sV<&nFlRX&9EK(k6k zGW?2CUltNmvJ?m#F>)0AK~xm8c4w-+eW*19J~tUj{}@}#AG!m&KJOTkZiX~loWrxyFi6hRz8C8HqqaX%-0HQmL)@6-rQVu;zBC2S3I=pU)u_@T+Q{ z$7rg#Iie=Tg~NKlX#G}A{|S_(hrdKb@Fj?VOITR=0aEuUawK1k^-O~U*$sb=CxhM} zp|}8F%emw?M?i!nTY(x6BR<1Pf%<3Zon07IJ1O_BVrU&O&LyJXh4yCmKFk^ORmT@H z^l+S($)eR|rYyG-x=7BK#GK%3jnAr%ZAtcjV@O%vy&&8Iq?#SG(`D+SabVkkhjLK!$+o&ja5^kbWUfoSY|F}!J!sK@|vT-?mhQfYKT8y2l;&j8O z1njG&vC{NHsL);;X zI{BpXEKVOIVuei(#eR7; zgSuR^^P5Dyg3;_``)VQYIuBV;2?SzN!@|VkYDH@W(zDuS3$K~Tv~pItx!b<&CbFQ- z=BwbKhxW%D)~GM~6J22&3u7-~q`T;h&}*Zp{$Qsxk2{-~e@UJI{08svJ%8`rEa!L{ zwrHw{UhcqRh_(*nB2oToWb?JnFu*moYi>_vhj zkS#xg_-4bPKB=VCP`Tl)3@{}A&FG#_jhPp{=mJ62X`vYHyL;w@p;?ICbG=+CfsTUE zE`s`M7VTgfk9d>GY@Yf;!gqT)V90JX^wFc~p_$-gB$F!cN7!RT+#SP0Gm@bvV&8&T zT0EVgYG%vyNF)pB_A?vzSBtBA(RlrVD7g#!B=W=EJAEnz_m(D{wL0!fou%HD@dmbt z1emTzTKCHTSQX3h>sAmrHScUDH<}?NVeD=`wF)O;VV)?f?(PX>>0mI8{iyI>2xlx) zqnj>*rqBOG%m~-!qrg5p6Q3r{jJ8=Ri(M^|chCRWy|9SEPm#rj%4arh{7_pK{BAfY+Dh{j<`nc9nIl+%suS)<8Hi<6!6Yi~VGu z)nlXUiFfOo8KGrvCq41;9&|;TAzvjAUaaj8Nmz6>!o5(=SEL*ZKY0U|CVRKEt@qz9 z8fFRL|A!MUDLKUQViga|n*sJH@ku+6=jwS|_cx+|8_E=f)&V`=T#R zfmmtEWqZd*)*^zxO~CgV>9*(Rzj3@^p|idp@%!BI?BW6!xbVIV@sH~yXksU#9urC@ zJz%KF_H1LFnVMZJ5AdV=1?7vFxylp6BM=y*-U5j?*=D#)X80 z7y$Ou9N-3T>UiG5h@}t8jPYbL9kxgcO_YvfmoY!N*wO8OjYGGmiQxu5!WkR1n_>7~ zE<-^+^bZ1Kl_j1}B!*q0(=IKajdyMkWn2gEpQivT1^3T6HU%RRc=Dy*hW*KF)n}_2 z(cjbx(vucuAyB{d@BW&Bd8bP4!z* z^)NwgG+0$Tzqu{F6Oo)e$}}!3dT-mQHnt>fZ`UOMzO>{|Nrka*TkUX^8&6AZH}XG^ zlX+yrkT8jSyEA0oPk+1`_#?{Xg2*cMS*s5kP{;3kGzllP-kj&_Y>YAw&a#wwSRUUe zwmCmPh7lJ>la@K8?0w!oJ2+7;<+Hz)SHjew;7OO9_tO~+vQa9{40v@U89%D>u=xMI zYsFBf!_hVtmwq#e`B})rHqD}g<5LYb*WHF-#)Zu4#+%d`7rc!!OdHj@sw~y&68*l{ zKaV^g!}R*GlughE>FbZ)0RUOyT4?Ep?}PrP>+#X31!d;5q67UXM*lwt4?LaHG|g^? zuJL%0xCbmg`Dr+xC97AAksaN#dIRfbtaQ1VZ2>W?@>qk>J^eBNbcdg2chZBOmOUnbAzDHX<`*u0J1 zifJpQJ>5~02h$MU+>!v2TC^Ds)-0ECY9l$!g^*!;d3n$#QSVp|242-p7^XXLixq$u zRq$&vO0Y>u`qo~xv0AF0kBLRqNgJwbiX`AoIA=KBt2X_WRTk%a98_-hE`NH!B;v5E zW}=*(dbH+54uOf4`0EPS1;D1DmXQB7$MGapQsJrySJONEJk*F4{XV$^7}(oP7?r{o z&7b%Gd|kK}9~?%``ioys%udp!$ww~>cTGNXM%8zoq0D+ouAV5_|}&% z2rA_VGAbfsYGNw%eAl3t6mZ_^W=S)=j1U;jUY~A``Eehy+93%=i4YMNW-AoRAFj-R zih)%7xlse_DC(&*@;Y~h*TY@E;);#L)I&F^qoFH5tdmeWOA~C_RK(S9?^f4 zPt|T;WD=(=llVaZqk+&+1L(XqT5LmB>gs)yk>$3x9BM(__ z9A+`mB#zJQ@~X-m%4x0aS7n?}VwLFEErqZ@A5m6!@DYa-GixFr;t@v z{GMnKaUE+Ewo`0(?3fX?Bhgdj1LTS0PM$E}G-3{$%icJXyoEqx>N@0c?0p{Z;M_Y4 zR{g=ciSZvW0yuw~KE-}At5e!laa!mgL4HU^VK0 zSL2qzfpKWRx_QIe+;}gqRkP?m0eSMBkvLI3Nlp>)`W`cu6IN^p^uSC1y8xo0D_tWq zF0Mf~gBKwGe6;~-4NfcN;CwfS*MO=R(4_g0Tk-u}a9VftOCq<gma46$L_Li1NnHkIUeX!@+@{E?C_#nZ#-Jj{=Qa>(3lk@NxpQ1Rl{Cxl> zYlT}9NB>XhqsZJPjjo<{V~(y78jEm7W9tSG0x#`Fp3Xx^3r|01_$nO8>krem#jha6e+msgFUx;PRFzP zIrUx+JW_95fAL91>|SL2si9xB3}}P14-wi*yC(C@wi=MW!Y(ARR?5>h`knHKAe1*R z+yQa`Ha?1U0<5hXn`r>Y5lLLH;+xUW;u&`lRT`^|p~%%=u$YXn*Q;Y?{axas5-(oz zgV6nv%x#I_Igw9tMNROYMSFBNU{!5W0*^;io$W&XprQv3`ptd5iAm>=dc5~FkjPg@ zGjdmLGiWM3T^ejhFUYdI^B%f4bshU{s<*G+7OjQrQDes3yBhN=wgN3ctVHaDR%<2*Swce3L2xNI{AHQTL5I zySh@@*(fL|z_;3;{r8V3H5z($ogQY|^W&)+sY%(2v}K4m@o=}rG6#GkjBL<_K-?ih zyj-%jl(bI};?_1dN2)C9^?I>eT91n_d!pt;eENuLDJo6 z7vZ_wO^+#EiN~)&Q~p4sTNHoL#`$l1+ua#?mt#Qc`fO|7oK~e!g;wNc>xF>X9616y)9>8+6CSEip-s3K> zuJ71KSg+4nZp%Bn490&e2XBzus)p3n(J_hElK~aDF+&h%*XPU}>Q@jQnuE`Q)%Mwz*8-rx|@)<+KK2)7vQFGLbrcDt?)OZ5WYbl_+pO$w+uKwq4` zGe0Dyq?9Y8CuvJ2um_W!Fvu|*-EJ&LOR!--K9SG&y&CEv1M22N1@9l&!zNMRx<69jHbM1RN zDG992hmysZ0ZyOxy^OmxZ;)S)nd5P(=m#{~{KTvQAsg`eR?DmXyU){thq5Z=^VWJu z0V-+#QlyCT+FcC(BNJ#$7)k(zW?K#4ObCh?v zX^^V1qs>uub378kMbt~kVc;?GEN;%4e%7Pc;b z?k{eJU)EwMf^V8Q8FV`{_?f3R#~DC8b~EXdJ`#AQp>bbW2^DMQYG$o<1t)@jgm@ z_r5+Z9?eLgSsQF@TqN^o=JCo8FLSARWXk7nXjh*}o9uN{;j~yj5(xpuRcK``uOAuF-Un*fz6KNW<5gGZY>|9g zP~kInzHFyAu5mu-l-;MG%|Pc5v==A$DU$UAC;7ol*V}Z`z=}8kwy$`Q$m!}GkX=AWUQ6cN$FtNCb%~-Iy ztyXJ1MjV0{fDS&~=zxb&OGn0Wz4(Rj!hcsdVx}|SaeZ(mG_+Wo+4H9n)FvY*xG*|$ zL^&Oz-`-HtUu(G7WP%)?8MJJ7sS~|%iHOFelwYJH-uOA=J(DhU1z?o7qs6lIb4kq5ii9zYWpU#RB$Epz+UpKcG$jD=!p8bjr z25S%eah+Z2voAZo2+D&2jOL^Hn>(ut?d|PW*OwNKhoj%*64+ycWqPiJ{~MWKg(aQ- z3H1$!vneUEolYx^geQQh_Y0_vv$X4rAJYehTGc-rTS1T&7xVWp4Du5DcwBcg0zsKF zun@8zms@VMzu9(nHgq)JgFxOq^T^ieYzhIP+$qVYqe}iY1ns#mF*nII;*5k|7pWU}OO z7+pIu6$%hDzw>nVJIhsD@}1aoSzes%fiE^$2861MW&o%OX|WRNktroOK;_>%y{9s> ziXBn+A@7A+UT$R9ueE9opm^9lplvsg#V@jcpy1Osg+@B{LLVs@K#WZZHstFfOc=&(IY9?&}`;v|tBT z9#Ws9l?{XTshHE9yeii#_b{1Fj?p%Sqi_pd5wU2 zOEZNawoN=|qevhNC2(#9suMVjUt7`3q}u&ZHr3Q}Ep5^*6%=#47D{UfJQZ;mm2$q8I(o@zYum>$T(-(e2c;pQ_e|9s=Q9y{{$v4qBh9%%r%`uhe-n}5W5EtfvBiW;ykC3 zCm;JSXsPIP&ClDz7%dgc*M&QR!@wWBMb?m;<#G;7P$mdA9Bz5Bp;25gO_iPr4aeLU zWxi)OFVP-=oJ>CFKv1}g^yFZnm7VhnRsY@M_AiH!%TifW%Wr=p*5K^hJIR7O9UXM9 zZrZV3VQaucAi*JA!(ZYq)Ycl__484&^lk&h@}=R*)c5aM`1W(3+JZKVv*dh3hBZTw zZ?-EbU};OFu3P*(RLb_AJjTj(VQORD4LmwM-QW8tCipwBx61A200gW#dH@YO_QP^H zXG6iTJLSR!0VjvmO77G``ec^*Q*IGx96=>)wxib=C0;lS;9LjbMdz%Uj}A7#s(O8x}rgn0(UbfSZUk+Ixz*?)tlz0w@ne5`;ZPJX18>08kS zI9+b23ANJu)g*SD*k5l0`syGMTr7|5X2QJLqBXxJ*3U8KCei3ndnLg7{^qbh0RW=a zR>ZqB>3;wL$y{As(*WP-7pQc@Aa1%K_>40VMWzthn~gW2kS&=g*U>R9TfUJt^$L(e z^$49vK^I9aeJ7whGFBRGh=idV&A#-M2laq(TU)yqZrc0UP*J&E!e8*e-Klmq7k4l& zS4VF+1@MWwV(HbYurh{JQ?NCC37sf6m@Kr}TahhaePiTv_e6->3v71I?R-9{ zcV{98mSZaW^Lw;-%V7!xjl@R7A9hpOdBCxf zZR2?UlzwId32om$ZJ0cr`fz*pD2v%?nAk6FEEe02H%4+tQoYO_9TCZTdd1|Do-=8; zSS_fYNKG<6O347q|1yM?(adab&BaWC6dG+Xy+pzQskKO*FAJoq`)1VS*QE2_tpDvx z2!;h7Ny`EStol?k+;g;&3M+cAlb5pzO$o-2N(uC`C_CJE`qY_n+_$#7o z>iNmpq|$C-Ja)+|1N?+taId#lmJd^rAUl@!2Lf3z|UTta(!xpW`La(9rzW8D)P8 z3}};tNUALdt2YQ7A#kq&4AD1AO-*ebdjl+vKQ;^cz%##K5o>Gkk*kFerBh%kg&%fp zv+mDal`w2A&q5#&0gt{R03=xd2o4BPL4ZK`p5O(n`SP~EVPVnL-<%N&0Lp^yI$Ors zz{LsA`R9~600JRnqpYkfEiL^DER)`vJeBY{UewwefEIPHqiv9ZqN5h)4&e}UDtCjZ z#GQwW_;_o}gr!#h!-x0>5cgE?V7|M}SXx^C-Aqfy3s?2s!Q;_ZGN@?>SMob9uw)Dp zLLMZEOLyod!R7TB_?Mb0i<3)m`~}yRu~0h#E>vvbHgXon>!?mSU$lV7g3Fy71}Lb_ z)ESvRPyY9VgO z_++LT$LQhAnFwPp-RzQk4NDT9mQ zAy~)=ZsPBz$~11MR|J=)4D@Ne`2h-}wbu1V&HZ=V{%-pcc)EnJ7XmvQY>{`{u7K`j z`)%cJi__@^yDR72ii@5B;s4EQyx3r$gh6sSclWpo2oQXSt*zf}KtldL4gm;RXnX6f zn=&Yc0$GD*4d8OW57z8nn;wYB%(l)06?AZ+f{+O^wcIvwNF8F=aAJHL-hAclV}fh#y?@X9;hi7WaV(wQ zbKE1YIIr`(#+U3zFbHFeZXu5KhgwaBP*)B8bb$@?IeyQRhlAaW7V3AwhZ+vd#YYQ` zMohJa%hqzVf1b+^o}1j&x4^)eh~4vd`H-Ohp0+b#x(8Vcf?wzR_eGQ+f}sVnm+j1F zI`ysH)kW_f-3<^@7_#vh*Q>9srvFScE0`hrpDRn)P`u3XhVk!8(Su_F6HRs;iRXu?D3c+_Wq#jc<-Z5=>utJ>$QOCcp$p3=E8!pYA(++lTMN_wN4qlYKkDseoA$ zfZ_#2UiH+Q<1bDeft3eLssx;}(o!hIoRk56DjE)WS0b-(QG)oUh7E*RSi)It;o;~I zP6I>3Lqq6xT?Ge}e+poBDTGT(7Wf=QoqIJEwD^Z@RMNKUW7&JbV`Mj$mnNia3h|&Y zVx}+C-kC!LSZ2XrzowMw0_UQri0K{)jQ9rvz}PJRBCHcB=y)2OO;~N;ot|C98#Gx- zd2z{pAwDGkV&D~hrgqY;xh6#~AoM4eX6p*}*F!1%^UtxcqQb+&LqmW5XV^%~J8Hg_ zPjQ>t8pQR+ANn&Nr8|&J*X_Ey%I=z9tv^V4^gA`!FD3=uPTAE1oPlHy@FrUgHdJ=5 zzI>)rD1K7@=p@Lq=_0u?{dR92qQVC>fwKeiqY?xb{Z3UVgh^N*(_0T7_#_&agzjic zx#^aUqk9!A1IPwUIk0i?1xL$1ML>1)b=I=22v7A?SZHL^$zWKfcRo4Ng4w$*NL{DFq!t>DE@{vb2$SlU5riAD@@@pe%;%g6%Iz3bkg@CqaG_uoh^K#Dkg*u1v|-jifkzU! zTXr?D>_$PiQ;m>RH#(kWcDzg5B9wA(x%!2f?kYYsOMmY5jG-1O^`4hWv+mpe&*Bs? z+80?vAj6#iytM&HT?p5~pHPy}Me4TLviG`3vk$$ziNH~SDW-ugVOv5PxnOY2uhtj0 zRaS`RvlW}8s-Ga&3?Qq0yctrKME84mctojamyn~BP9a;pX0cei;r4<`Wh#IC29(q>MZA?fbulm7-R;_1&ZL#8pF~24WKqT%$9Mr z`G_Ls{7~B(1otp7WW(;4q&o;+t$hErfT6T~LgrdMtuI)(Ob1sRSXq3iureHVa~;s*6!dkE zgb5s#D|7@6G40fA%TEFSjMt7baU?L{GFd7i)(q3`%SPM@~b z=D^#fun2XyZT+!W6^}cGV@UeL;Pa}duF;9SL`A`xx)5cqCJBF-5ZUc&KS?DUMY2o_ zH@(My=XUNES?APF&u}lj>J5BHk0kdetBigA4CGBg{K+{8tHo7+R~{@IiC3%ef4vcI z?3HkRk?!zRn(<-bSoY1@RMcD$ElPVMtFFWjY$C{?3kqs(;{KT5(E0V``s-Tnyl(`n z{s`7q&hp!bDrIoHZ$e~ZOij#43Sx`zX^oXOnz%wl)+z-#XV-0PqHs@qxpiosVw zZ}MU^VX_}nGt&&)pF5UoBEPndsv&>z;4C+tWil24ZBB~nEeaLR>FLf?ijLq~JAt#_ z_V^8(WoGdK+w7-M4_~ld&g%9WQ+{4YGhF8?IBzfbCV)h(;?w?X^D=7K4}Du!HhCw5 z;u`K}M0Cp^fD*~>WA1xEECm=-5SEF|u#8Yxi^(s)wQntmn1=tgQa2@3#FL!g0wAe} zNiWXY;;oTmL66#npO<@0xBHt4bw^t#f{RM(6+v#Ufk|UB2k&ej;EVrf0U~O0;$n|5 zk|ZsH5t3*pC%1Xq`pD=Ui8nt7lm5r%3^GkM2A`~BHt@;@Qaue65B5LY92 z_qP4Tf9A__GmdX73FoD`RPMBkE=s%k)={U!lE<&iSO2q-8)~ZL98O;noC0$H>!GGk zX6)6pDTh?fPAFM5|Ic@oUr~6SS*Z6r_3h&FKE)tGUaciuw5PlN;HiX~`}Nx+e&7F? zm&qSsoU?;Rytr41;?eBpHp^=zoQiVkCB|#9_*;=Xv5ee})^i1tNp#+)AK$K5gIpK} zW(w+;aAV>w+6(>45r!%&*0Ge*kj$%&qB3({(}`M8bSXbcNdpPoU#|n)HP*i`%nwgQ z_wO`;m_YM>X7NZi*-PGpOTmBuBE?k#6$#)+Ab0u2aOdv(Z|;6rZQ&)rU0acE$7^80 zbIL=&U4ekxdH=m&UMnq7gy83N!aRi@OG$7niM*a2{AbAUM9X(itpuST_~P&T5sFjz zLl~LZlyVOIlzZ!KjV*zuq(pryk-JN^%3^tGX`)yg{{r_pgI2z-yK%!`$c)8&@&~{( z<{I(8e{Xz|mjl_21>>H%8w_}SJMSLP!S5EG8WT_%i{&QO$8dJsUrbDL^GC~z+1Q!# z{l&kv?35V&a(7iRs2R2-v%Jx$L_-d|5-8R~JvzJ9aOn2TJ9$|eM?qlLW7$pTql=GH(Bf)e4Wi~qGwf2qEJu{Sun;9{lKs<}$P01-)znR4StxuCUp zz?{4E`y1|3r8Im+cI(9tCXN8-1{F1jt;9<()5(%gK+B`j zgM?)tMW+Q+3zj31boaFe>1TJfhKs^4gV~;T0-*(dONA6(&n6}BcdOW^;h(gai>bj| zW2o#L3ShD&huVV$P3aJIY(%N7K(Ed3*NLz21Cn?epdL^0aJfU-`uU=AyqHnC+maAt z)vGXnnf6lsGN+U7x@NIj;^4Z>XZ%KhaRK!w6bmw-6zQ#CdvwXn05DZE377pv0-WPS zjxYzcW)Nkl5FzIfx)gKa;)zqK*F}~a4+(FsLsu2tk)S&S*ac?KffyNwoqn%2Esjkt zK7kP8=7KK?~s1~cC zb8SClA=3_Ef^`YF6yyfG4a%m32k)Q0IhSew@`!44)b8~3G=}RusjlOHn0h(hpyqjS zko$AD1e2;?nG0~3A$BGg=Of1bKhgkWf%mrlOV68GT}ii#jVVwWSB0|O=GzvJNE-3jlRAIX4@-L(^d}&kyti5X&-JHv0NU2x z+B$$4_x(FRuDQKEYtzJo_vlcVk00Jq++{e_nVf~&ZDceQE%hoWX_DgNT>vy=5X5O#G9v!0>LdM(x;nm$@Tr&>f_E? zjTR+K;2Lb5#=qv(^m6_Q(Ri*?mb>}s0@OK&vOmv--(7|!deGQalZnzRq)`LhV z5*)NZ$j4y{E&?%T4tH>H*O_ai1BzjhA#ga2VkyCO>ad%C06|d)4irJJ54vWklnT#& zlb|*oh$UB60HuC`OpAVBqJIABNZuvT_lS38bhh{$gNAJNqY|{SSIc2JN0DK2-k(4F zkW07WoUVoNzNmAs+}gf+4+;;=OP;8aN>Rj$l_~a977vO&UJ%&n8CYaK`gTH!Z}iKg zTRiH-$14z{t0EV9@Yf?$u71ED%ap`DJ0IDYssa}PD(SfD*6gZKvN=yxN=ha8uTi2~ zxo*(U)Y_2{683=$Tl?qy{LXdoFHJXmwamttd2Vze=U-Oymee_BXadiKinj<_mw4Wi&L`+eXqI+1Q*lL2`&MEqC<{o%slKB2aNG(%jKi4jxWUEh0Lz}GQaU-_p0GGrCR(MAod#Vs5F@iuhaU=} zw_T@T;L#^f0cPWyt4{|VZ6IDan;J+94kA~qf+tj@cufy9q_LP(%IJ2{XpfB2P|R0; z{j!3Hej|BnBMX?d|M4mAlQl+UU22D1`29TP38ck<9m>hmts2;u=lrt-1rWg@4 zxp8-cA0)oC=m#i*I^SNO=4tu1wz|Ftd~MHFYEWya|rD;Ar9T%c+m zw#n0UUthVssfrnyC|-c#lvg|bGQxn_GqQS$-)J!y=rv(U{@B^;80!(LXSQcBpJW{C zpX1}r{*>0eCi3^9pcuW4dlX57JJ@BjW`DFdmjNo=JUodrbyfOs6i`0yVt@*_Q@QR? zN(vf~Tx7HXB55$**I_l{u}MIhHKLW4t^(wcyPhAm%;`iGstY}ATB$ehImWO{rIQTT zfAnN-d{!>fELiPnAeY2REi4)*wQy}kw7nW3NT|TcM~XA(()R|psboe*QO5|aMT6cW zpPa`sE25d!>;%^YSaU#m!dg?#N$L6km0#JV9IV7Vv!MXVe^T4^Kss7=7jf)!eAe|p^XBLZ_iZ|NHh*>tD>@RuRT!8wbp z4DrYdbKH}~BSStLmSGPf0bRY{q5-q^>3pSL3!%Ei3}`q&D*H{cNFBS|O^U@2GB~7b zGHRMJA%=ftqlu*s>Hr(f~Gl z@XMBGwDj3afp4oCS`A?UVzK9v)U_~N^X*NT`gxsMqV0KAg;FscpVFjw4Ewz+>d)9>;lzoBb%Yh0? zOtET_v1PW#{ivhfeG z2cHAPF~Y>tzanCEuC1<-cK;rK*KRtBBB=zJHhCZDIavw`9@IR^k?{o^4&xVMcYeM( z`qg8QDBBfuHb$^%VzCwkw{}HPb(v^Z7uNx4*=B*4|BbJi?EUc{wgDKGi6p!>!vOF# zo~--vjmcc%T7U??v1YJGwX|1+onuy!xr;3E~jIYu?$+imdEaVz#QO8 zJ8Ta7Uw2QH8P)+JzeZi;Q9I#R8Z}mV_sNLJIJ}D_j<9Dh7$XI-Y}4^UgAS&?@(*@5 zhe?K7pHk59%{ImXbsN!h)TjpF6e$xCS1oS*&4xfCYn&^ZG_uh09Izr$afVy;+>M^V zp=|f=ZW&Egf;jGOhSTiF0|1CJJAGDpRE4sYiUM)zeybfY5obvzh)A8IGgZ!Sq_kS{slrrYa}KZ(VdwcOI7R~l$=yr zSN0V|P0LxTuI9?i5mr}=We?oTf!bgn#Op@gGgX#w5Cfi*aT4A3ldKnte5w{7*WEz| ziKVqI(cTT>ls^N)R5D1LdkD7CP-#E}C5KX>y7hYhThGxq!`MujS`{WC+*ieNAbG^3 z>vcY;)zsgy1(Xel>u}*t<%gf2!mc@-?VZO8rDd;SkpV>Vxenx<`+S3N|H}AM=#*`> ze2a>dY;9*TBtb%*Hw|VOz30e=Lo1x z+%SOJ#H^fJ4plVpu-Vz~$`WqA#y6<|6wg>D!^Td7D0|Vm#z90|quKHelH*4zrFyDR zu4j2Qt!=NBy_+9Oj@V5DB1oA)>k|Zrnb4zu?BEb^XDobxlYeGZH4yjHxYy_ZUqA;L z`SK-i(IcE}WDP{MyHM)OBVqjIEQ+Mz>v__(`9welB?dYJddy*z_0~GCj(ZZrhbr0r zS8jji6SsXnT-1T7Gxv<)KNwwJu1~U!`IiD}HJU&6G}1_Bc;657Z3mPG^Kq+Fi-SjS zio<{+xVOjTc);rrCSI4Wp;huQs5NH-WJH6AtVZ(#c}kZ_?z2A((8s*5j)tmcrgJMy zRkqDp@Z>_RBg_zJT!H1H1jOjMFk~MJnLJ7oUj}^?)2a$O_;~!gWEj+n`@g z+0K?-MV;VY2>KG@BVE*Yt&VnCj;*jMF~H`3{*v9oz>IAN2;KhD0PvkYI|~uMfgrEsS_vv-^d&!0M49t4j~J;iP-1~dKXwB z#~~S#34F#OkaC2yBgB9cHv|@~u#gZ#K-Bj|onm*;225C>z`^Ls zh^=quawI`PLxZ4w7oUOKPR5WXb!xG#_C&$Of2dAeTA76jR_#gi1;X5Q_Z6MhJk_&D) z&!A{%o3R2K6-LR6mvANDdRTPZ-o$nd4bc!Sl;z0z4wU=)n(F9OkE_Y-h-h5mnOds= z?Er+{uy+fbT}oQj@QOBW)_0*aN~+l!QTJh!_vHTmKDb%4U^4vdR>ub1b|^xbVlhPN zhwu4}f6C7PG8oIu+u-{gKSji1wWI$I5G=4O2V4#j_^1f-0|5PC{+HL%o z(t+a7hoQyW02*didj`p&HE9NfJQyM`?<}w*VY4{kX-4kS)%hR)#W9^vI0PJ1%)HiL zUQZq~r$48Ef&nxH*~@*r4v`>w?M@*lr(A1O`g>_M(=I8r7PN2v3xk0KV#$m0f|Dfc;6g*+ywP5Iwx&=5FgLh^;n~ zF_BdFvaK29XW6U<&}9sxBUS6sVV*##px-TBCE~WmAuk)iI{d&vEg72rDwtCK?hXmb zcCA!{$^Y>s4W&=;8qmeAw5}xftNw+vdg=}~$4iVb#i7jCr}XLG>cc5+(scN;KwM=5 z#Aa9nQn-1QR$HT0X+p=~DmdTNGHT-#4*Y)2YW@6z)L?+9$-z4Splhu0=r*GY@fpAJ zr^E_NP$xmIXn`J9sIL*+G*p<~0+R8U*i1F6m*7$s2(9L{K-v_O;eiEZG`)86iB9hN zdVN4JP_c|8(*uH^EU6)onb~av)fvw(%D!j@v4$CS>S0`lI9{jGN~`-0SRipnpSYhU z28Mb`+#4OroS1Vg&YXaLO$mKtLx}y;mZC%ggKCOa2`p0E^g5J`p8syrND9 z$Z~n#-;wea-e|}42|pr4*&VqmOVRoLGoIVIJkN9lq_brP4Vfs)sCddURfTm;O?^yJ0r=}U zA0TnQAZvwfy87-=2M=JWOt3cv-C{jSMgPGG&{kJ7F?Zx1B2E3rYBvw&|DW$ckuNBo z5Wkv?e1Ag!V@=COjDxv*v#pn$W@jtv>|GDWOV+!czm5Uj^hQC8FA0!$EGZKmf}D5+ zv$V`15+JD{|B)33==m=LB|~hmJNS^|olmIKFpW#OJ!)R%lcq=+S zJNE?=TN59U0Q7oAV1!{E)Nio01Exdj|>F;rhHT^ z{Ms<$wb{#AZ>~TB%xYd*)!CGWVr?z2ob#Otd9g@yMw*Ty*#uxTtegF6SOu`$=@U~G zredUGH#Vu8!#Sd%o~c9Fy2p{JW5ajA{^36pNUzjTL|UG!)nU}6Tw250)c212#Cq$^ zwUdyv4G-Z+^I5W4Bj&%Nw+i}Ecz$IsXcpoUJM~G&?#JNs5U-=mCZ`;n4%Ld>GID(5 zkzmu2HO38Odr_QfaK)(p>8^RrQu<5O^@`*O?kD1scG)9(mJ{Mj*`A15lDLf~BV0}# z#)IDgcxsx4(qK1W(%*u^qOQ#2u@kL3IG)+Rx!f z>SipEkj0gCVB zcPcAyowWMajeFNf3e56QbLmGtdexe4YGv}tR9~7tCZgttx;FM6nP?ejncH7lsfEjU z$xX~O$Xw;9<)G~sZNp#N&A;t=;+zsGtwMUi~|`gD#Q zl|Q2WwsI#TvQwVRWzSE? zUL46n(oSBby3SXfEh8Ee#km6gRJqZA0SKVv{q^gDSs_#fh!q`ML%i2`NrvwNn!Poy zCh@xCIYcitiVha0&5kko_tx4Zg_JlEhL`JStdDxIM#nH|VXR?{sFCb9QPVK5X`vF8 zXFS2mhHwmUz?wm?TC5n-;_v#p|KP=|fz zJicr&V9IBrI9dr{Gd@0n9Mo+qlYTV|3NrVtWCVy*p$b#djCm@`PvlWS`E4RWd<@Dz zGQvSPnQ17GS~IN3OFyo3&eqt7s7axju-z*^vcKPM42TAeaM@Gi$iP`qi@6Ph8^_a% zi@%!1wk5~JTB84!N>DWiC7?J>Py!N4GLeMJ3Of@!+wo1)nM|NNi{e~*L$l8Q0aQKC zf5~N8`0dynbeh7%uVr3LDSbaQ5oK3x5uD}XnGg0fCh7WT^w-3QFpCP zNpE8_z#J8EV6#6|y}I9{18+@gRllLUj?(-?}Ibb>mD)Uq1>l@uGyO20>ekjlyk zl$ZD(je<@_0}qsFI)+`+tbq23QUB(AW)w&kJ97U97y~IGAz1(dU`?yN-Rg;^xYQAK z4rITF4H}xeujp9cl)pb{8i%G+G*XwOz84sw98~<01IaZuYooU6vrXf4Aa-wbmB;oH(Ma;9lgf^Vw&u}CAsqe1^_Q) zv?L1PaNy|Wawlull!o-`1ONMrCEY-GG zZ)Zi1SfBppWa#mhbN@4MvNy5(!w>KR24C7`*D*ARKRN|mg_@eeyY^IHX0|fjqCWHn zn&9tXi4V$TmcQS7mL_E*E(nXz;eQynnfgfZxdQ-g?D2YQfoz)(q?VVEY?(b(!*YpEU5C)qomaR+9a(6 z(25f1h5H(VwPUvnoQ}e1rMPKmrxAKaKk34vW#i>+iQT$M{mo* zD{Rm$z=~rtrbk67As<_Ow0pi-BjHRtUgv;aA(S**ZT;xiUhDQ<)Bq}`ukNaU+8NyP zcH1xMLD+wSZv$%7CjpyKS(1no$lafug4}&L_-q752$EK5eH=hadh3s4zlYV6I*UY$ zxrwhcY^%hK7N0adv+#=I4nLX&Xvi@tP zR*2ODK=MB6HeO!h^nVYV6a%L(2KDQ`X^wZEmyNERFZJdt%4{`t(U7nj1sR^67S7zo ztR-nEG9@@cQ?>T4rF@S$*Ai!ini) zP#Ik$`ov5NNN0Q!?~?RCeKX6OrRmoIuxl$sOKS!oEt}!k027tpuJW$!!GgF9%Eop5vwthzw^l7|F}Odq(9kKHx`o8y+AU{!7Gc zEYc`{`|$Q7*@Ri8^&4l~j!VZ`U&FJ+iI@rPiGf(eJI4sO!_#*Oqc z>5J%z_ugQVSYT9fg6U}Yn-whb(p0&tl`iAKYI!01*zaOB9FO_lcj%Q4#C7WT{yv7J zuXP-6t=aBOik*;5Br~TTg^Ed~Sj_e2%I7Th@e+P>(=(m=M&nBwUXE!u#`kk$$k%d~ zE6FW^QUCX1Yna!VLoI&-`@U!tEsb{--8)%h?KGjtRPPQ@y=$Rh7Sa%_c>iU)i_fhj z*w2riQI~;XNd<$N-NvB0si`g@LBZ+5q;jDn3^ySGSFZQ>@03yjoclL&tqW#JD*AZ- zAz8(iE$NJ?bWNwXcs(Z|z`8;^b-+0xR`!2u4!P{QQ#$BQ_Q?^Epi zPJzvdGWrMLi_JUjVJmy+)D6aR%n3EsO-WDu zyOYCxdq3N4jV@vxEJ>5bYn!t-l3F$#k9k<9zM29ZF`9=ugYm^phO^taBy<*u2V`Hy zHycZh_j)6d`*=MrDKDp;NM=B0cljg<^r+5#?t5cE%4+wz;e{4;Y^!yE=BAuD$^)nDT3{$q-bY@i$yy zQ_^YDyBsP^bjAjx->~ZLOo(h9wNDo8y_UQBi1L(XOhn zV)#fy{)AI~BjL2otxz1O8#iFOjClIwA7@ z>g@@f!W~chYed6iZprBwJ;ew@x8@JKP;&G=OV@B@R5e@>q?6ouKI-jN&Fywl4Bwrh zX1J5Z+Hl}*ee|N#A;znw3e2#sw}Q?#NDs<^MTVnI7BVcDl0={WEvAQ4NdI!PAZ+R zFx^1Hl5#oO#!GUasuXk)j9;LECnv`pSe2lp2@D8GW_FIdY9~CELD=qiGtrhUo`cCM z|G|3TNkB$Kp^jwiIGAr4kLmF3j2^vq8W_^I?S(BXo_x*D_%bm_dQFc%Iyihl zWW@6i7}YtSvNCIComAIOdizuwILySbS|;x8?d|G*awmEHdVR{$LDY0XdUbH~U5xiR zr-NI9&`EO$9$tP3-nsHiZCOigvu(Xvg3w%ryynD9{R+PeN#*2irZ&oor`Rtx*T?XYBBJ8^4I9&Bn1?f7?cbBjdDq@a6%;9$$2hY*=eJu3?N}r(eB}{haQLRFagH zy@kYWDqzlzO)W1YHaFMS)J!-#a}M9n*a)@Q zy?rK6#yGJqxxxt7pv>*=77Tm3yeMxl&r(!EgMPy_l2Yoxab{UuxTPqiMN z7ZE6OX4Z8^z0Hi;?ygypSVpGRxY#l!g7--NNCs@vFrCe_*TapjgcoPk)z#y$k3TK1 zl8G}#Z&yD_e!M-eVIQ$X3wH0dXAPSMZcdogU%G_(`320_13qvtbYjeoe7f-DeHiaX_j&6x`0A??305cF zsG5K-og5)}%8ZXoI+8Zi58pqWhui=%e!H$t8xl#C1%8ff#sP3x=YHGy_ODNf+remk zd`~ek@=|r%S;5^TJG;B{8yoL<(a^B0Klad<6kc)25wTFb`mq#1_aeg){8DFCVce+Q z+xOU=kD&(vrf`YwYv5z!^8*S%ZKx<`UNh_ov%_x|&2w>$Q*VqXqf}9p&#ZC8ulx>c zsO+$KxhKa_V?f{0`&F~D){!af()rP7ehg8<)2bsK4Dfml<%}g;)zvNt8XK>&!)vR} zz8VLs!H9hh)@VQUh!6~9!Sl`>b8ByY_=8axvIl2!Cr~t zBeTaZjpBf(ER?W^E)g)Pm;`D%jmhL{q~F|F)dz*`J5ZFAI4h^^VE8kQy(V=FyHa+Z5EUR2t%`V`iO)P6TmAL(H!vcnGL^gcdknJvp5PZ~2tS3P^v6K*d zvzBV>>z$o~oCm{CO`cwYJ-M#`twYF?@_%1-d+`EU+~2P^&;Tb6!fmw!FOztCy(f|( zhLOZe=fb)XXZbyPtJ-1jQ>(u>8(MUIeY{BgFT4KePoPp64w@HkD{1DmSWt^-z$wU7 zm|(c&O;78YZe3gz2~zUjK0|INA@NmJQ7MjlO*|%3^O1DaEyEz}d)U&$N8BAS)peZ8 zz+WQg0kft4PIFe1sce&)JcEXMvxIqMaedrqt`Sw`yuR@2ToaDv>%r9@fd!M#&52jQ zmj~gpy+_26W1*V_Ex97}oV~bF`JNp$-@9BC4}YrrU=+VD80WCIS0ZFlqdheZX{+t% z*-EG#zQZnFMoRrrm)(L@5>H0=GNG9{?st>Xdg_I-+wk#ZYGZg|dRHkBpK3q(Yx zz-X_aKlL%|kIog9*HE2Aq@3>U^^YZT-9-Xx@#Nm0;yuPt`qvIyP|dxV-BNbpQgkZv z98UkL@$n-b>2KCQX|uujj|_WoIvPXVugEMze9r1+AGRp7EC24J!He^AJBf|S>gV@vPeEPB`)N~AS zE+?AHv3S4G^Q+KpP7dKyyzv;WM{3sU)jLH^iN)p2hDG(xpV&(cN3xNxrVa;_85HCM z@?z&do|uH?w9H3*7B37!Lq`3rp(Ix&`6!7taKv+#iyUT3W#yVi(yR5B>c|I=d z<^X%Y=e{>_*bY3AxzQEP^f$RrMV{(#<|5{YpoxZE1roA(PonaLAf(@qn z`p;jka~SrnFV>=H4kyy6Vfs~)g8%-U#RzR=rv*j;++K_&Yv+OiOgLQ}u-0-l-Pk!) zlhO{foPBljsa?K8jHL|m>D;7oOPX5uwjFq$SD`)d>YS-k5~vpxrX1`oA7V)(sU1Uv zP6nT5L|Lt><9KM*9{D;#eSj_HeSkb+(I_ighR{B$D&bJb44zG9h2O^JbLs3X#@gPn z3wneBXOe6=rX6^)bJ^bxc*m`*uYQoQv8lwS903=#(8Q;WN&$5>wUPJd_uyrd4+>_k z$XH6N?V8wOeb{<4){7Uvc7ODNq7w$oU5>_SE+trERyx#(r9wx}MprMUTUv&;t~ytq zGX<TqL*^{?T^yCPxcn37O!@QXg{+k>vZ?s|!Crp|$j%z#V$ zPz&GD2~&!`Ra%CWY9UANC3+(9L;zuFmAC1QddQkR9{D$$X>NJWFuLs@9? z3AmS+bxpU8-BZhgz1CVhe|MqoSjpDZjr+Ke^_YWQIpDyEK^n=;xSK$`7$06!PMG$$w*BQ0Q0FBv!V zJE92}mtfX;B-a>Zb5ctmaT1W2y1@8dzDjZ%hQ6pp+2A4~9@Dz^L6zjwBze>hrnVU4SiEp-WvHbnPt5f||i#jvSJV!2}1ho`$bkFEObt zesiW6;fED}4q>=+v<&imJ>R{-U|F1X@hJ*Uny>VRLTxyu_9rK!zzGcY-*$wRrPeYh zWO?U`i>vW@Pfe)EFrE1py@J0GzCVcnGpH_U*AF0Eb1w3{14~?s(nQhfmY3Ok|D3$! ztqxC+_MCXc%H(78xXDcA-BjhxRZ%z@TB-9X<4GQUnJo(P!Z7wGM*wPT;5VWa=6M4;(K27hajt>{NX5Ki$NbYGkN)v+_ZwmM z_=w(=p9q<~Zy3qxCa~y-HQ>mNc(dq*ea%WF#3Sp4ojVPB^?8CW%ZLZ2mZ#@9{Vl%^ zB2BxCc;k7O>ytsAUD{ZZ^LC@sH2EORU z{_CU8_+AI)PRI#lD1G|0_XLSdWJydmi9?Abq5}_~(g4QeRW{yMtugQ?5h)T@&~Uo5 zX=}V{Pk<08`mv@y!-RnN(AY<3V{^olfFPJg?c(NSN^~PjY%#0%n_GHlr%5nMHE!;1+pic?>r)jTsO^4|7c5DN}ev`!AqrT)6vv5(Xw#-S?YZmQ+S& zro}|5J_$^Q56Wvu{CaX{R~H(g2~0iwJOrATiR5D~f_`t+Z!2DtlMj8`mxB>|fX{FH zYGC0VoPwKMg6+!eRI7f^F`#Xw{%db6d6qR|c&c{^*}SvxCwK>8JS6EHgvXZ|iqo zUlt`8iWT4*JpHd>j9g!yw)*10&^-jvs~MYCPWnV()OybbGVW^s?@KUm+hcNBJS;07 z)*0?WYV6jLMV4V*QA6pDdKvc*ZvYQZ9#|+)t1^m?j*2?PhspSiLInA?Zk6h}xxduD zD1iJK>r10Xdr^v~H?TS6(iXNL*>70~7~NIrQ#MP3|4rH$(Va9XL7jj*dpe_%d=iS|(kHi1^G9LThZ=;c<1lV_y#XJDr$C#i~||z<)&q z%o_A2q|L$0U;rLQXwv-xinzBNnOAjpxs}lW&8_(8Pfsl;CJv?s2iaRv$EK?2GJgeP zlZ>m*fTZbDRyy_CjSH(N#cv9ENl=90q^0%9u$=3C!73EZT6*H)5npR(TJmH-)EBkL z7~IpD;n=~`^mq2renNkHLbg`}E+~acA@?`tb0ArKy$S&;S5dfiDC)+0ID!)UD)D3ve$Z0e2^+K4!23M~kP>TA!r?#e4QE43uycno=-*;v8p@ zimw?_!DTj;rKR)k3Q>g)c;GZiJRSowSbcF02mEw0$!(B2y@6&aZXYH~bmzepzDS54 z-&~*V#~@)Lb{Ue`xjhD5#>;@J6riq0!gdn~F)^kbEonU4p){0V8VYGRuOg5s6(kW6 z4={L)UYi9LzacTrIxrn$T}mqM{H-joQf3=Eczm}+U*~~fHQ8*SYU`U=?9SOfvXm6- z&CM>5Gb|=CrY?L^R%SbaWx7_c|MVgN^&Vzwkd&INcjPf&Us_t+-F^1r#nDbx9s9~y z>;#!0N@GNBCNwJ9-82y%5fl!=U=>mh53R8AiCQ|{K3_8b_)(o%+0aJwM zIAV0wpw+`0HIR`94ud>KS*PRsDZhZ4I8(S1f?;pQ{srjxn+`=mUa92KKi|NH-Z1OJ|L9Hs9@ z4@oPfDnmj7;^JIE&hLIG`Q55AV=$nhfG8+VqWMN920kzRyL}pSh!A5B3Z`Q;Modb# zLO#w$cH#RJs}*4f2Va98F3=@lind2r4B-|z1b?bO)til_duZsZ8yOkxV&HfkF;jSr zgbIl}<_iVNDJ3yVMNe;G_-i`%eZf>_X={a5=Mu{~Uyy!gII`bOlPQ>{^r6+x-gvc# z7-O&DeK~PiyHh|L`Ws8ve>)9-}UNbVkJppKEQF1m{2eZ z#N;WnATj|h#{{^?@XwH8U#}<|MM)q<&@G$G)!9?h-o%;iMTb3t%bQF2NIus+|L*sz zl!`%ZwjTaxwO$dF#}VKCM?Pq;vX~l#e{~+yq5F$C^}ycEZa|}kaA@A+(!4IPYmMQz z=07APHabm~Yll~smFc7@FRb_yR@m;%`nU?VW9|Z3mCcXOZ1oKZGc)+Lw#Mg&eQ-BM zZ|yzq>qv5$PZuj=h>y&z)(*d)5 z16nG!(XDM#nIvI|S*hR>Q8>eCYvtwVg^elME2%gmq}wsm)5|`{TKb`<2*T<;pg~ z30&SOV%^zxi;!MtDPbHx-L$YXr2^^`%S?X;b$xLs5K;xi&$4QWRYZi9b7Zxw5uIi9 zJiTAAE-kjsfcgj}sSTY4-MW?=NFfHz7w!%q#ciQy?o>sdmE_i6L86eXWyu-qRA@NZR3CV6o z8lmx{?;<)+B4jnhkZBL#RjRFsv7I9$Y0jVQwl1`ozH``&zBf%^X3|tED4CVBZ2y8s zQpQLDPSl>A-a$-U57bL^7OHe4G&QAO_tGVeR)E<;KAbY_f~L6Vzmw6SD4!l)J8%ZJ2%SA# zhP(biKRE{nEq#AjATn|q4NZ?Ab~sKSPVz^uJj*wo)F$6+3*i$d_huV{VuZMV>jjvHLYl{G?Q@@Lo_!=0TTu3-i3C~TQ%!>IpXY2O`B_5c2@MZ+i= zAvDOQkQq`LQTCq6UYQ4(l~Bpb-o&xDvPY4<3fUvsn{2{;y^p@1kI(1#``!2BzVGu_ zIp@63d%Rw+>w1psdS!ysJ>r9$u{OhZ+Ce3e-{oU zEYy|fp&^P+qa?#B9M>L!V9C5WXwM+mEqqt5WJbs_h=nnHup<=T9)fp_P^Dr} zIGc>!SR+|h(PXRnYroi`3YSk`;|GHoS;A-i*PofePZ*25Z&9>+Sa3y`rr)Pl`7(v` z2tWNc)0sk-%_UpdmAB`v{;+c(&EOeyEz`}o`tp!LnG4Kv?aiWGDt$h*LoR5yyYa12 zy?VO342(HnZZ@t*Uf0aPL%XEp12Tb-b+K1T;hGcM?`~~r8SM4x*XLt- zcvP4aB`UkJ%xi^oAWSg1R7oflnGw`u15=?yGe^CqDW8@i-e7mt(3Ut)xK)AQVP36d zRhDU5TUDiLu(Zy|;U0yYDKh%=aW+0! z?l~u!NYO1Foxz^;+Ett7pZA&DraMlxw)*Vu4i3BRXBRfykK}Gkj`ITv-{1dIi3t#c zE?2{AyXNi_FjgAN7w+yTrz-T7J4FgO?Kwn7y_p}_LIDS!#>D5CVK$N{aEU@8RYC3C zFlOC6$JSf-IXrRD$obDLS{NYVi&F6qozqrz2ou53al%jEpe{CY-40^y@~k3%+OQXn z+#`jV;EIQ=gD$!fqhot`#<&vu*C5M)8N14jhj4oHBU%gip#o-ar;qpEm2^})Pg0|t z)~=j~I#ozq&=Gc3uQ%`H`rcbJWKK-9P)N4Ew4nPtY1j*QBr|CB==^9qy^r7=axb0+ zaiX6d)e|BOZEb7qXd#U^GM3O%NT%QuYU%+f`E1U?w@)(W{@{xXmDpK#;dy+I%{a;( zGsm$1h(HH3?!>?TcUQE^UI1MJJo$rW2V;#i(jEFv;?LHnfilr{4xn$5C!g=%&~b3E zFxF5)J7*;YMM4%#to)xJuNNN#EPXV@WqzkO-=;l^{C-a>#8Gj>FoyC!Vbn)bUoV*< z^&ejZ6)S_kuy5S`xxu$V=TWajO=gWHNtzL(;0;1%`sh*)e*VujH3jfI8RYjOPH}VD zv5!N$-_;HK{h4&iD4hj0JA&seB@QbF6VHxV$jB}%;A@tA7?Ygs&DS(B86hgnD1p$% zNGIr8V!N&=^;DuuHD9z{2_L^}dO979$fCxO{{snb#)LYxp;?3*a^NEfe9(ckEAQY=ih$t(u<#+n1J|2*rkhj}S?+x~ zx^;vSPz><+Yuwq8=c2iQ0SttPP&wZ>#QE)O^BN{ZhD&j9xTPi4KetD6iFELUaWr!( z7CvDqh@wt^GTY_BOn~RTrPf1eoF`oHJxkN0DOOhA^e-30gRQ7@f#Yl%JU3`)UZK&b z25cYWPY_|CYsILko}9^Bvsg*c_fKz#6jbwiR1zsh00r9Kx!+FP1372VL1ymltLe3y z_m|;dKANn^?j^n7yV(@*;jB!05b(R~uC>B`(UzXyO+4W2X}~J*F}*$zqz~`LvIAvh zLja?!WPAVxcWDjw*LWSwoF-CWLXwz?Xu2VtElvHV21?PvqL=`enZ@K*(XFGeFN|l< zWYBP6fhjI-=;~TSD@y7=h)qAfC8#`ODK)|-Qu;~oX2md^@84PCU%V1H20DGFFE`q( z&3sn-*sQW$x+tfhQ3olDT=(+Q$Ta!QwDB>bp*vfEj;4PWLHa-|wmcxckfQeQbyb~rP+VvS6X`P45H?bLtFd{ zK33V9OwJ!4!J^AtfAIv~c&`#AKepWExtLF*b%v}O^k$5^YNZ8a`!9o+UNaLAh*g;E zp=^w0jK7%uo>En*I#4!*oa{L0ltV$D!Pe8uICYv(=m9MgS}?SWiGqkrw4hplUrwSF zOZcop;vXE8J1f3D(Xs9An7_eyg+R2oW-YX$TX=gaVP8eP+hSmDfMf9Vko7E# zG5C%O6t$k4GspQaN_xOLW`5=9@D`9#@=c8^3P8Q{5Q(iq< za$i%L-f)|y@Olc35{1o@lkj=o^9NXH+m4bp&{#uESh&?&lUBwQmaCCh=gJeU5IOzQ zLD1QIeX#0v{`Uy!fVBVb-t!jJ5PPD*tcis{wR+C?v-p@Fy}WHn2@AnlJx2_BQ(ew0 z^-bPzEe#K@w!O44I&Ty5B!VRHEN^Vqaab%FxXb_#zucxdg2B}#e(n7te7l`fIj>@#zGb?!SKh`l5Ud+FI4d({)>oRGl!T=c zzST)AnTu0z?sij_Y=6B;FC?VxtdBH@yy$36*_j8X2D$U{^74hpu--m9I4-_zP5dmr zrppw$?Q9pzaxl^d(`u>#H8wdZKl&Gu^X#1e>{%}?teWRpJbzAPVYrg5f*oM|b$o$h ze7?cq5|nrA&eNw)hmZU>2VdP>*8Th7&~&*e9LhTG!gXL_UBf}H9eKsEAh84UGJg&M z3iC1o2z&6a+v>=u#k~5CBKQk=eI&!pS#!6IAPGD-cs;-jPvl?!o7;FydU3ZP zL9NMr-^Ac8J>57dDdsN6ks+sdUTQVQaVt>ZXUg%$ySz2B$g!|k;5o%bS?Y_4DlPF? zDI6V-kNQcEyzwjq&O}DaVQ;D-%aM{wvyx@+HkOOTQ~Ko1gZqK`=5K!inwe7K*FRIR zwu64XN_=$v0m0#oQ+&sM=8JJRkn?1+u4Uab*rWTIa^y`%@}IL=N6sdz2=%LJH|AK4>@lKb=|5L6k6eNC zXDg>U$AR5nPO@QF;5`v5%mL2>YkK?XXj8o+jqVG~Uy@*=KKtd_Y>wwaap~{BSihPg z#t#k^!2IO_Xnk1YXTRAhGM-n*+`ur{4hO68auu4llXMyLnd?W8Q$ zZHkP{Sm(kkH=M+YXs77VHPo0p6?PW+GM!)6@Q`A5bs&FbyR?M25T+6L^~=an)bn1{ zMbGS0Z!_#+j{WHaacRygA^62p~n0<3}#9kUChw#T5Z6^dhzk(=pN%PPge<{ z7kX=}Ll!@EftLbS?uZ7?*YljL1MAraXA=XS7>vL2!}RwKI$=q9Tl#u;Kq>QjZGib% z1%%cHDW00(GkRNZHF-G&7bRdrfthY`l*o5Jp>C7EF7`cUMIFnBnyCUq z3{`Vm8*ETjv3VAmO}Ae^o5gZGnsuyQycuN{o6mXkW^k*!VOtDZ9wB_ccwIt%MB+Gd zV&k7tL}MDfIivOb`GJwR1Is4jBjVk+Xd3jt#tYl9UYloh2)Wuy5PlDi6hV>?J0pyZ z>G2V36UsFp9ee_eUTe+6~j1&n{fsE$Ckx{%)^oVyiThwjWw>GuBlu;!3~y z4ju36zQGFqw5Na9dqPN{Zn_F|x5q|Kn)d-Lgx}lM0)w^LV9;t`>B> zc(mV=U*nZf&j`)-o*!7fo*FhQ9z`jcmGH&zE^z-n9!^|Sf0a5@B0 z3@oSH#bF@8q)WnFnOL{g{8vN%%)1*IY}>3}GC@MQ!W)bB*Cftx`jFquYi{Vh;uETj z#3wAQ2v|v1U+zJWY}LvZY`5nfTHs#OChRL*xY~SIecpOOn)X%G?^5t!zc+_=bJb$C ze$>|y2qC2fnb~*B6Tzyfay1|is*V^Ke7`?2fdY;iwLWKHymt^{|8w@yvqb^HVRHk@ zj!e4iJExAgQi?04D<$ur458wF96;Z1*YB!~PjmyVC|Vl<84}US=KCOPF)52m*su?l zg*ROESiP#HsyaI`NXc_|M2|~l35>6ZBD6k=SP8kml^!g~4`Dt#-m%Xb{q58tkHZ=W zUJ0L!i_=1P$PN3xTRiRh+S~rv1K{p{#LX2VQD){DFpQs~t$za*Pw}up>rE2{a9+6V z*mcrrVvMYlpWC|^)ibkfOb7TTY^)7%;lwSAMJa^s`hzEsB2`uwq% z9`;jTnZeaX*qu#{f9jMY?C+!SgTms&=J396eHZ<}x<1Llv|vD{#Z)WmqC=)dV;OU5 z^bhm`pHV+i;So4D$DR2sXh-$K4K}uoeozCMU7W4n*jLz;dSa4#8{A0?gZ*zQ`~6

LHtYf0@(17keXrW-K)X;+#pRxH;4E{20GH;*8_q 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 Date: Tue, 11 Aug 2020 14:19:39 +0800 Subject: [PATCH 233/285] fix word typo --- .../com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java b/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java index 205a7bd80..42779ff71 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java +++ b/singleton/src/main/java/com/iluwatar/singleton/InitializingOnDemandHolderIdiom.java @@ -45,7 +45,7 @@ public final class InitializingOnDemandHolderIdiom { } /** - * Sigleton instance. + * Singleton instance. * * @return Singleton instance */ From 1683fbdf9c1bb73414d9ab5dca1d7b535971cc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 11 Aug 2020 17:17:25 +0300 Subject: [PATCH 234/285] Clean up Transaction Script --- transaction-script/README.md | 30 +++++++++++++------ transaction-script/pom.xml | 2 +- .../transactionscript/App.java | 2 +- .../transactionscript/Hotel.java | 2 +- .../transactionscript/HotelDao.java | 2 +- .../transactionscript/HotelDaoImpl.java | 2 +- .../transactionscript/Room.java | 2 +- .../transactionscript/RoomSchemaSql.java | 2 +- .../transactionscript/AppTest.java | 2 +- .../transactionscript/HotelDaoImplTest.java | 17 ++++++----- .../transactionscript/HotelTest.java | 2 +- .../transactionscript/RoomTest.java | 2 +- 12 files changed, 40 insertions(+), 27 deletions(-) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/App.java (99%) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/Hotel.java (98%) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/HotelDao.java (96%) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/HotelDaoImpl.java (99%) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/Room.java (98%) rename transaction-script/src/main/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/RoomSchemaSql.java (96%) rename transaction-script/src/test/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/AppTest.java (96%) rename transaction-script/src/test/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/HotelDaoImplTest.java (95%) rename transaction-script/src/test/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/HotelTest.java (98%) rename transaction-script/src/test/java/com/{ashishtrivedi16 => iluwatar}/transactionscript/RoomTest.java (98%) diff --git a/transaction-script/README.md b/transaction-script/README.md index 7d784101b..d4e4795c6 100644 --- a/transaction-script/README.md +++ b/transaction-script/README.md @@ -9,11 +9,15 @@ tags: --- ## Intent -Transaction Script organizes business logic by procedures where each procedure handles a single request from the presentation. + +Transaction Script organizes business logic by procedures where each procedure handles a single +request from the presentation. ## Explanation + Real world example -> You need to create a hotel room booking system. Since the requirements are quite simple we intend to use the Transaction Script pattern here. +> You need to create a hotel room booking system. Since the requirements are quite simple we intend +> to use the Transaction Script pattern here. In plain words > Transaction Script organizes business logic into transactions that the system needs to carry out. @@ -26,7 +30,7 @@ The `Hotel` class takes care of booking and cancelling room reservations. public class Hotel { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); - private HotelDaoImpl hotelDao; + private final HotelDaoImpl hotelDao; public Hotel(HotelDaoImpl hotelDao) { this.hotelDao = hotelDao; @@ -72,27 +76,33 @@ public class Hotel { } ``` -The `Hotel` class has two methods, one for booking and cancelling a room respectively. Each one of them handles a single transaction in the system, making `Hotel` implement the Transaction Script pattern. +The `Hotel` class has two methods, one for booking and cancelling a room respectively. Each one of +them handles a single transaction in the system, making `Hotel` implement the Transaction Script +pattern. ``` public void bookRoom(int roomNumber); ``` -The book room method consolidates all the needed steps like checking if the room is already booked -or not, if not booked then books the rooma nd updates the database by using the DAO. +The `bookRoom` method consolidates all the needed steps like checking if the room is already booked +or not, if not booked then books the room and updates the database by using the DAO. ``` public void cancelRoomBooking(int roomNumber) ``` -The cancel room method consolidates steps like checking if the room is booked or not, +The `cancelRoom` method consolidates steps like checking if the room is booked or not, if booked then calculates the refund amount and updates the database using the DAO. ## Class diagram + ![alt text](./etc/transaction-script.png "Transaction script model") ## Applicability -Use the Transaction Script pattern when the application has only a small amount of logic and that logic won't be extended in the future. + +Use the Transaction Script pattern when the application has only a small amount of logic and that +logic won't be extended in the future. ## Consequences + * As the business logic gets more complicated, it gets progressively harder to keep the transaction script in a well-designed state. @@ -101,11 +111,13 @@ in a well-designed state. patterns. ## Related patterns + * Domain Model * Table Module * Service Layer ## Credits + * [Transaction Script Pattern](https://dzone.com/articles/transaction-script-pattern#:~:text=Transaction%20Script%20(TS)%20is%20the,need%20big%20architecture%20behind%20them.) * [Transaction Script](https://www.informit.com/articles/article.aspx?p=1398617) -* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420?ie=UTF8&tag=gupesasnebl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321127420) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321127420&linkId=18acc13ba60d66690009505577c45c04) diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index e53bb4b4a..5dc2aa981 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -60,7 +60,7 @@ - com.ashishtrivedi16.transactionscript.App + com.iluwatar.transactionscript.App diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/App.java similarity index 99% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/App.java index 98762520d..59ea5363d 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/App.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/App.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import java.util.List; import javax.sql.DataSource; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/Hotel.java similarity index 98% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/Hotel.java index be9000af5..c24ea4f68 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Hotel.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/Hotel.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDao.java similarity index 96% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDao.java index 71d9860ba..b06211905 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDao.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDao.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import java.util.Optional; import java.util.stream.Stream; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDaoImpl.java similarity index 99% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDaoImpl.java index e64b64699..240f96892 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/HotelDaoImpl.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/HotelDaoImpl.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/Room.java similarity index 98% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/Room.java index c4ad7bfd6..fedf4ed21 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/Room.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/Room.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; /** * A room POJO that represents the data that will be read from the data source. diff --git a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java b/transaction-script/src/main/java/com/iluwatar/transactionscript/RoomSchemaSql.java similarity index 96% rename from transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java rename to transaction-script/src/main/java/com/iluwatar/transactionscript/RoomSchemaSql.java index bb2e2374b..4d919137a 100644 --- a/transaction-script/src/main/java/com/ashishtrivedi16/transactionscript/RoomSchemaSql.java +++ b/transaction-script/src/main/java/com/iluwatar/transactionscript/RoomSchemaSql.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; /** * Customer Schema SQL Class. diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java b/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java similarity index 96% rename from transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java rename to transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java index 755a95653..425d6e153 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/AppTest.java +++ b/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import org.junit.jupiter.api.Test; diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java b/transaction-script/src/test/java/com/iluwatar/transactionscript/HotelDaoImplTest.java similarity index 95% rename from transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java rename to transaction-script/src/test/java/com/iluwatar/transactionscript/HotelDaoImplTest.java index 6e907fdc0..6dbbc8ff4 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelDaoImplTest.java +++ b/transaction-script/src/test/java/com/iluwatar/transactionscript/HotelDaoImplTest.java @@ -21,10 +21,11 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import org.h2.jdbcx.JdbcDataSource; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -79,7 +80,7 @@ public class HotelDaoImplTest { dataSource.setURL(DB_URL); dao = new HotelDaoImpl(dataSource); var result = dao.add(existingRoom); - assertTrue(result); + Assertions.assertTrue(result); } /** @@ -96,7 +97,7 @@ public class HotelDaoImplTest { final var nonExistingRoom = new Room(2, "Double", 80, false); var result = dao.add(nonExistingRoom); - assertTrue(result); + Assertions.assertTrue(result); assertRoomCountIs(2); assertEquals(nonExistingRoom, dao.getById(nonExistingRoom.getId()).get()); @@ -107,7 +108,7 @@ public class HotelDaoImplTest { final var nonExistingRoom = new Room(2, "Double", 80, false); var result = dao.delete(nonExistingRoom); - assertFalse(result); + Assertions.assertFalse(result); assertRoomCountIs(1); } @@ -119,7 +120,7 @@ public class HotelDaoImplTest { final var room = new Room(nonExistingId, newRoomType, newPrice, false); var result = dao.update(room); - assertFalse(result); + Assertions.assertFalse(result); assertFalse(dao.getById(nonExistingId).isPresent()); } @@ -141,7 +142,7 @@ public class HotelDaoImplTest { var existingRoom = new Room(1, "Single", 50, false); var result = dao.add(existingRoom); - assertFalse(result); + Assertions.assertFalse(result); assertRoomCountIs(1); assertEquals(existingRoom, dao.getById(existingRoom.getId()).get()); } @@ -150,7 +151,7 @@ public class HotelDaoImplTest { public void deletionShouldBeSuccessAndRoomShouldBeNonAccessible() throws Exception { var result = dao.delete(existingRoom); - assertTrue(result); + Assertions.assertTrue(result); assertRoomCountIs(0); assertFalse(dao.getById(existingRoom.getId()).isPresent()); } @@ -164,7 +165,7 @@ public class HotelDaoImplTest { final var Room = new Room(existingRoom.getId(), newRoomType, newPrice, newBookingStatus); var result = dao.update(Room); - assertTrue(result); + Assertions.assertTrue(result); final var room = dao.getById(existingRoom.getId()).get(); assertEquals(newRoomType, room.getRoomType()); diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java b/transaction-script/src/test/java/com/iluwatar/transactionscript/HotelTest.java similarity index 98% rename from transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java rename to transaction-script/src/test/java/com/iluwatar/transactionscript/HotelTest.java index 26bf4b5cd..ab0265244 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/HotelTest.java +++ b/transaction-script/src/test/java/com/iluwatar/transactionscript/HotelTest.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import org.h2.jdbcx.JdbcDataSource; import org.junit.jupiter.api.BeforeEach; diff --git a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java b/transaction-script/src/test/java/com/iluwatar/transactionscript/RoomTest.java similarity index 98% rename from transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java rename to transaction-script/src/test/java/com/iluwatar/transactionscript/RoomTest.java index 9ea8756bd..6755c2e5a 100644 --- a/transaction-script/src/test/java/com/ashishtrivedi16/transactionscript/RoomTest.java +++ b/transaction-script/src/test/java/com/iluwatar/transactionscript/RoomTest.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.ashishtrivedi16.transactionscript; +package com.iluwatar.transactionscript; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From 4ffab7da85d85a31ac235331aa72c64bb00c922d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2020 14:21:58 +0000 Subject: [PATCH 235/285] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c8daddbda..249fbce0b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-120-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-121-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -248,6 +248,9 @@ This project is licensed under the terms of the MIT license.
Rakesh

💻
Wei Seng

💻 + +
Ashish Trivedi

💻 + From 2b7949ce6a115018c5c424aa8b381eda6cc0b203 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2020 14:21:59 +0000 Subject: [PATCH 236/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 135cb1260..20f64f82b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1093,6 +1093,15 @@ "contributions": [ "code" ] + }, + { + "login": "ashishtrivedi16", + "name": "Ashish Trivedi", + "avatar_url": "https://avatars3.githubusercontent.com/u/23194128?v=4", + "profile": "https://www.linkedin.com/in/ashish-trivedi-218379135/", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 870d44b1271d489be02848ca06e5165d45c4e153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 11 Aug 2020 17:25:38 +0300 Subject: [PATCH 237/285] Fix layout --- transaction-script/README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/transaction-script/README.md b/transaction-script/README.md index d4e4795c6..3ae3cf4c1 100644 --- a/transaction-script/README.md +++ b/transaction-script/README.md @@ -16,10 +16,12 @@ request from the presentation. ## Explanation Real world example + > You need to create a hotel room booking system. Since the requirements are quite simple we intend > to use the Transaction Script pattern here. In plain words + > Transaction Script organizes business logic into transactions that the system needs to carry out. Programmatic example @@ -80,15 +82,9 @@ The `Hotel` class has two methods, one for booking and cancelling a room respect them handles a single transaction in the system, making `Hotel` implement the Transaction Script pattern. -``` -public void bookRoom(int roomNumber); -``` The `bookRoom` method consolidates all the needed steps like checking if the room is already booked or not, if not booked then books the room and updates the database by using the DAO. -``` -public void cancelRoomBooking(int roomNumber) -``` The `cancelRoom` method consolidates steps like checking if the room is booked or not, if booked then calculates the refund amount and updates the database using the DAO. From dc7bf6190d02dc9bdf93c2815984d06c9d228a05 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2020 14:29:44 +0000 Subject: [PATCH 238/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 249fbce0b..2435298e7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-121-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-122-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -250,6 +250,7 @@ This project is licensed under the terms of the MIT license.
Ashish Trivedi

💻 +
洪月阳

💻 From 41dacc2e2ecd25ad5d96721d9616febd0d6e7881 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2020 14:29:45 +0000 Subject: [PATCH 239/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 20f64f82b..7a9aa42c4 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1102,6 +1102,15 @@ "contributions": [ "code" ] + }, + { + "login": "RayYH", + "name": "洪月阳", + "avatar_url": "https://avatars1.githubusercontent.com/u/41055099?v=4", + "profile": "https://rayyounghong.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 31471acb69bb5e41d0668cfbf10c3d8e083b1861 Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Sat, 15 Aug 2020 21:47:39 +0400 Subject: [PATCH 240/285] Fixed most reported issues by SonarCloud. --- .../iluwatar/abstractdocument/AppTest.java | 15 +- .../com/iluwatar/abstractfactory/AppTest.java | 17 +- .../com/iluwatar/acyclicvisitor/AppTest.java | 16 +- .../java/com/iluwatar/adapter/AppTest.java | 17 +- .../iluwatar/ambassador/RemoteService.java | 4 +- .../ambassador/RemoteServiceInterface.java | 1 - .../ambassador/RemoteServiceStatus.java | 23 ++ .../ambassador/ServiceAmbassador.java | 7 +- .../java/com/iluwatar/ambassador/AppTest.java | 14 +- .../com/iluwatar/ambassador/ClientTest.java | 2 +- .../ambassador/RemoteServiceTest.java | 2 +- .../ambassador/ServiceAmbassadorTest.java | 2 +- .../async/method/invocation/AppTest.java | 16 +- .../java/com/iluwatar/balking/AppTest.java | 15 +- .../java/com/iluwatar/bridge/AppTest.java | 14 +- .../java/com/iluwatar/builder/AppTest.java | 15 +- .../iluwatar/business/delegate/AppTest.java | 18 +- .../main/java/com/iluwatar/bytecode/App.java | 10 +- .../java/com/iluwatar/bytecode/AppTest.java | 15 +- .../java/com/iluwatar/caching/AppTest.java | 17 +- .../java/com/iluwatar/callback/AppTest.java | 17 +- .../test/java/com/iluwatar/chain/AppTest.java | 16 +- combinator/pom.xml | 6 + .../combinator/CombinatorAppTest.java | 13 +- .../java/com/iluwatar/command/AppTest.java | 15 +- .../com/iluwatar/commander/Commander.java | 315 ++++++++++-------- .../java/com/iluwatar/commander/Order.java | 8 +- .../messagingservice/MessagingService.java | 12 +- .../iluwatar/commander/queue/QueueTask.java | 4 +- .../java/com/iluwatar/composite/AppTest.java | 14 +- .../java/com/iluwatar/converter/AppTest.java | 16 +- .../test/java/com/iluwatar/dao/AppTest.java | 16 +- .../locality/game/component/AiComponent.java | 2 +- .../component/manager/AiComponentManager.java | 2 +- .../manager/PhysicsComponentManager.java | 2 +- .../manager/RenderComponentManager.java | 2 +- .../data/locality/ApplicationTest.java | 12 +- .../java/com/iluwatar/datamapper/AppTest.java | 17 +- .../com/iluwatar/datatransfer/AppTest.java | 16 +- .../java/com/iluwatar/decorator/AppTest.java | 15 +- .../iluwatar/delegation/simple/AppTest.java | 15 +- .../dependency/injection/AppTest.java | 15 +- .../src/test/java/org/dirty/flag/AppTest.java | 16 +- double-buffer/pom.xml | 5 + .../com/iluwatar/doublebuffer/AppTest.java | 13 +- .../doublechecked/locking/AppTest.java | 16 +- .../com/iluwatar/doubledispatch/AppTest.java | 16 +- .../com/iluwatar/eip/aggregator/AppTest.java | 15 +- .../iluwatar/eip/message/channel/AppTest.java | 15 +- .../eip/publish/subscribe/AppTest.java | 15 +- .../com/iluwatar/eip/splitter/AppTest.java | 15 +- .../com/iluwatar/eip/wiretap/AppTest.java | 15 +- .../iluwatar/event/aggregator/AppTest.java | 15 +- .../iluwatar/event/asynchronous/AppTest.java | 16 +- .../test/java/com/iluwatar/eda/AppTest.java | 16 +- .../com/iluwatar/execute/around/AppTest.java | 10 +- .../java/concreteextensions/Commander.java | 4 + .../java/concreteextensions/Sergeant.java | 6 +- .../main/java/concreteextensions/Soldier.java | 4 + extension-objects/src/test/java/AppTest.java | 9 +- .../concreteextensions/CommanderTest.java | 30 +- .../java/concreteextensions/SergeantTest.java | 28 +- .../java/concreteextensions/SoldierTest.java | 28 +- .../java/com/iluwatar/facade/AppTest.java | 8 +- .../com/iluwatar/factorykit/app/AppTest.java | 8 +- .../com/iluwatar/factory/method/AppTest.java | 9 +- .../iluwatar/fluentinterface/app/AppTest.java | 8 +- .../iluwatar/flux/dispatcher/Dispatcher.java | 13 +- .../java/com/iluwatar/flux/app/AppTest.java | 8 +- .../java/com/iluwatar/flyweight/AppTest.java | 8 +- .../iluwatar/front/controller/AppTest.java | 8 +- game-loop/pom.xml | 6 + .../java/com/iluwatar/gameloop/AppTest.java | 6 +- .../iluwatar/halfsynchalfasync/AppTest.java | 8 +- .../database/MongoTicketRepository.java | 11 +- .../hexagonal/eventlog/MongoEventLog.java | 33 +- .../java/com/iluwatar/hexagonal/AppTest.java | 7 +- .../iluwatar/intercepting/filter/AppTest.java | 8 +- .../com/iluwatar/interpreter/AppTest.java | 8 +- .../java/com/iluwatar/iterator/AppTest.java | 6 +- .../java/com/iluwatar/layers/app/App.java | 9 +- .../java/com/iluwatar/layers/app/AppTest.java | 10 +- .../com/iluwatar/lazy/loading/AppTest.java | 9 +- .../leaderelection/AbstractInstance.java | 13 +- .../leaderelection/bully/BullyInstance.java | 21 +- .../leaderelection/ring/RingInstance.java | 18 +- .../leaderelection/bully/BullyAppTest.java | 9 +- .../leaderelection/ring/RingAppTest.java | 9 +- leader-followers/pom.xml | 5 + .../iluwatar/leaderfollowers}/App.java | 0 .../iluwatar/leaderfollowers}/Task.java | 0 .../leaderfollowers}/TaskHandler.java | 0 .../iluwatar/leaderfollowers}/TaskSet.java | 0 .../iluwatar/leaderfollowers}/WorkCenter.java | 0 .../iluwatar/leaderfollowers}/Worker.java | 0 .../AppTest.java | 10 +- .../TaskHandlerTest.java | 4 +- .../TaskSetTest.java | 4 +- .../WorkCenterTest.java | 5 +- marker/src/test/java/AppTest.java | 8 +- .../java/com/iluwatar/mediator/AppTest.java | 8 +- .../java/com/iluwatar/memento/AppTest.java | 8 +- .../model/view/controller/AppTest.java | 8 +- .../view/presenter/FileSelectorJFrame.java | 10 +- .../model/view/presenter/AppTest.java | 8 +- .../java/com/iluwatar/module/AppTest.java | 9 +- .../test/java/com/iluwatar/mute/AppTest.java | 8 +- .../test/java/com/iluwatar/mute/MuteTest.java | 19 +- .../test/java/com/iluwatar/mutex/AppTest.java | 9 +- .../java/com/iluwatar/nullobject/AppTest.java | 9 +- .../com/iluwatar/nullobject/NullNodeTest.java | 13 +- .../java/com/iluwatar/object/pool/App.java | 12 +- .../com/iluwatar/object/pool/AppTest.java | 7 +- .../java/com/iluwatar/observer/AppTest.java | 9 +- partial-response/pom.xml | 5 + .../com/iluwatar/partialresponse/AppTest.java | 6 +- .../java/com/iluwatar/pipeline/AppTest.java | 8 +- .../com/iluwatar/poison/pill/AppTest.java | 8 +- .../iluwatar/privateclassdata/AppTest.java | 8 +- .../iluwatar/producer/consumer/AppTest.java | 8 +- .../java/com/iluwatar/promise/Promise.java | 1 + .../java/com/iluwatar/promise/AppTest.java | 8 +- .../com/iluwatar/promise/PromiseTest.java | 2 +- .../java/com/iluwatar/property/Character.java | 2 + .../java/com/iluwatar/property/AppTest.java | 8 +- .../java/com/iluwatar/prototype/AppTest.java | 8 +- .../test/java/com/iluwatar/proxy/AppTest.java | 8 +- .../iluwatar/queue/load/leveling/AppTest.java | 9 +- .../load/leveling/TaskGenSrvExeTest.java | 11 +- .../com/iluwatar/reactor/app/ReactorTest.java | 11 + .../iluwatar/reader/writer/lock/AppTest.java | 8 +- .../java/com/iluwatar/repository/AppTest.java | 9 +- .../is/initialization/AppTest.java | 8 +- .../src/main/java/com/iluwatar/retry/App.java | 7 +- role-object/pom.xml | 5 + .../roleobject/ApplicationRoleObjectTest.java | 6 +- saga/pom.xml | 5 + .../choreography/SagaApplicationTest.java | 6 +- .../java/com/iluwatar/semaphore/AppTest.java | 9 +- .../java/com/iluwatar/servant/AppTest.java | 8 +- .../com/iluwatar/servicelayer/app/App.java | 7 +- .../iluwatar/servicelayer/app/AppTest.java | 10 +- .../java/com/iluwatar/servicelocator/App.java | 11 +- .../com/iluwatar/servicelocator/AppTest.java | 8 +- sharding/pom.xml | 5 + .../main/java/com/iluwatar/sharding/App.java | 8 +- .../main/java/com/iluwatar/sharding/Data.java | 2 +- .../iluwatar/sharding/RangeShardManager.java | 6 +- .../java/com/iluwatar/sharding/AppTest.java | 6 +- .../sharding/HashShardManagerTest.java | 2 +- .../sharding/LookupShardManagerTest.java | 2 +- .../sharding/RangeShardManagerTest.java | 2 +- .../java/com/iluwatar/sharding/ShardTest.java | 2 +- .../java/com/iluwatar/singleton/AppTest.java | 8 +- .../com/iluwatar/spatialpartition/App.java | 7 +- .../SpatialPartitionBubbles.java | 4 +- .../iluwatar/specification/app/AppTest.java | 8 +- .../test/java/com/iluwatar/state/AppTest.java | 8 +- .../com/iluwatar/stepbuilder/AppTest.java | 8 +- .../com/iluwatar/strangler/NewSource.java | 7 +- .../java/com/iluwatar/strangler/AppTest.java | 9 +- .../java/com/iluwatar/strategy/AppTest.java | 8 +- subclass-sandbox/pom.xml | 5 + .../com/iluwatar/subclasssandbox/AppTest.java | 6 +- .../com/iluwatar/templatemethod/AppTest.java | 8 +- .../java/com/iluwatar/threadpool/AppTest.java | 8 +- .../java/com/iluwatar/throttling/AppTest.java | 8 +- .../test/java/com/iluwatar/tls/AppTest.java | 8 +- .../tolerantreader/RainbowFishSerializer.java | 13 +- .../com/iluwatar/tolerantreader/AppTest.java | 10 +- .../iluwatar/transactionscript/AppTest.java | 9 +- .../test/java/com/iluwatar/twin/AppTest.java | 8 +- .../java/com/iluwatar/typeobject/Candy.java | 4 +- .../com/iluwatar/typeobject/CandyGame.java | 6 +- .../java/com/iluwatar/typeobject/Cell.java | 4 +- .../com/iluwatar/typeobject/CellPool.java | 16 +- .../com/iluwatar/typeobject/JsonParser.java | 6 +- .../iluwatar/typeobject/CandyGameTest.java | 6 +- .../com/iluwatar/typeobject/CellTest.java | 8 +- unit-of-work/pom.xml | 5 + .../com/iluwatar/unitofwork/IUnitOfWork.java | 3 - .../unitofwork/StudentRepository.java | 18 +- .../com/iluwatar/unitofwork/UnitActions.java | 18 + .../java/com/iluwatar/unitofwork/AppTest.java | 6 +- .../unitofwork/StudentRepositoryTest.java | 24 +- update-method/pom.xml | 5 + .../java/com/iluwatar/updatemethod/World.java | 1 + .../com/iluwatar/updatemethod/AppTest.java | 7 +- .../com/iluwatar/value/object/AppTest.java | 8 +- .../java/com/iluwatar/visitor/AppTest.java | 8 +- 190 files changed, 1426 insertions(+), 661 deletions(-) create mode 100644 ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/App.java (100%) rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/Task.java (100%) rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/TaskHandler.java (100%) rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/TaskSet.java (100%) rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/WorkCenter.java (100%) rename leader-followers/src/main/java/{com.iluwatar.leaderfollowers => com/iluwatar/leaderfollowers}/Worker.java (100%) rename leader-followers/src/test/java/{com.iluwatar.leaderfollowers => com}/AppTest.java (83%) rename leader-followers/src/test/java/{com.iluwatar.leaderfollowers => com}/TaskHandlerTest.java (93%) rename leader-followers/src/test/java/{com.iluwatar.leaderfollowers => com}/TaskSetTest.java (94%) rename leader-followers/src/test/java/{com.iluwatar.leaderfollowers => com}/WorkCenterTest.java (93%) create mode 100644 unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java index aed63f303..dca4f040f 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/AppTest.java @@ -25,14 +25,23 @@ package com.iluwatar.abstractdocument; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Simple App test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ @Test - public void shouldExecuteAppWithoutException() { - App.main(null); + void shouldExecuteAppWithoutException() { + assertDoesNotThrow(() -> App.main(null)); } } diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java index 4036cc9b8..238ff76d0 100644 --- a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java +++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AppTest.java @@ -25,12 +25,23 @@ package com.iluwatar.abstractfactory; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Abstract Factory example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/AppTest.java b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/AppTest.java index 4b9a7ec6c..842779fff 100644 --- a/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/AppTest.java +++ b/acyclic-visitor/src/test/java/com/iluwatar/acyclicvisitor/AppTest.java @@ -25,13 +25,23 @@ package com.iluwatar.acyclicvisitor; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that the Acyclic Visitor example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/adapter/src/test/java/com/iluwatar/adapter/AppTest.java b/adapter/src/test/java/com/iluwatar/adapter/AppTest.java index 3bf8e1010..3748c64f6 100644 --- a/adapter/src/test/java/com/iluwatar/adapter/AppTest.java +++ b/adapter/src/test/java/com/iluwatar/adapter/AppTest.java @@ -25,12 +25,23 @@ package com.iluwatar.adapter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Adapter example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java index a80806851..42b09d617 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java @@ -62,7 +62,7 @@ public class RemoteService implements RemoteServiceInterface { * * @param value integer value to be multiplied. * @return if waitTime is less than {@link RemoteService#THRESHOLD}, it returns value * 10, - * otherwise {@link RemoteServiceInterface#FAILURE}. + * otherwise {@link RemoteServiceStatus#FAILURE}. */ @Override public long doRemoteFunction(int value) { @@ -74,6 +74,6 @@ public class RemoteService implements RemoteServiceInterface { } catch (InterruptedException e) { LOGGER.error("Thread sleep state interrupted", e); } - return waitTime <= THRESHOLD ? value * 10 : FAILURE; + return waitTime <= THRESHOLD ? value * 10 : RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue(); } } diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java index 5b4995134..eadb981a2 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceInterface.java @@ -27,7 +27,6 @@ package com.iluwatar.ambassador; * Interface shared by ({@link RemoteService}) and ({@link ServiceAmbassador}). */ interface RemoteServiceInterface { - int FAILURE = -1; long doRemoteFunction(int value); } diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java new file mode 100644 index 000000000..f9faebd0e --- /dev/null +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java @@ -0,0 +1,23 @@ +package com.iluwatar.ambassador; + +/** + * Holds information regarding the status of the Remote Service. + * + * !Attention - This Enum replaces the integer value previously stored in {@link RemoteServiceInterface} + * as SonarCloud was identifying it as an issue. All test cases have been checked after changes, without failures. + */ + +public enum RemoteServiceStatus { + FAILURE(-1) + ; + + private final long remoteServiceStatusValue; + + RemoteServiceStatus(long remoteServiceStatusValue) { + this.remoteServiceStatusValue = remoteServiceStatusValue; + } + + public long getRemoteServiceStatusValue() { + return remoteServiceStatusValue; + } +} diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/ServiceAmbassador.java b/ambassador/src/main/java/com/iluwatar/ambassador/ServiceAmbassador.java index a9d34581c..57e444d88 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/ServiceAmbassador.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/ServiceAmbassador.java @@ -23,6 +23,7 @@ package com.iluwatar.ambassador; +import static com.iluwatar.ambassador.RemoteServiceStatus.FAILURE; import static java.lang.Thread.sleep; import org.slf4j.Logger; @@ -58,14 +59,14 @@ public class ServiceAmbassador implements RemoteServiceInterface { private long safeCall(int value) { var retries = 0; - var result = (long) FAILURE; + var result = FAILURE.getRemoteServiceStatusValue(); for (int i = 0; i < RETRIES; i++) { if (retries >= RETRIES) { - return FAILURE; + return FAILURE.getRemoteServiceStatusValue(); } - if ((result = checkLatency(value)) == FAILURE) { + if ((result = checkLatency(value)) == FAILURE.getRemoteServiceStatusValue()) { LOGGER.info("Failed to reach remote: (" + (i + 1) + ")"); retries++; try { diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/AppTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/AppTest.java index c9a4d09b6..186f13715 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/AppTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/AppTest.java @@ -25,13 +25,23 @@ package com.iluwatar.ambassador; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ class AppTest { + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/ClientTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/ClientTest.java index 12a93a1cb..bab319bee 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/ClientTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/ClientTest.java @@ -37,6 +37,6 @@ class ClientTest { Client client = new Client(); var result = client.useService(10); - assertTrue(result == 100 || result == RemoteService.FAILURE); + assertTrue(result == 100 || result == RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue()); } } diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java index 6c45acf66..374a909f3 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/RemoteServiceTest.java @@ -37,7 +37,7 @@ class RemoteServiceTest { void testFailedCall() { var remoteService = new RemoteService(new StaticRandomProvider(0.21)); var result = remoteService.doRemoteFunction(10); - assertEquals(RemoteServiceInterface.FAILURE, result); + assertEquals(RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue(), result); } @Test diff --git a/ambassador/src/test/java/com/iluwatar/ambassador/ServiceAmbassadorTest.java b/ambassador/src/test/java/com/iluwatar/ambassador/ServiceAmbassadorTest.java index 8eb55b30a..48d128115 100644 --- a/ambassador/src/test/java/com/iluwatar/ambassador/ServiceAmbassadorTest.java +++ b/ambassador/src/test/java/com/iluwatar/ambassador/ServiceAmbassadorTest.java @@ -35,6 +35,6 @@ class ServiceAmbassadorTest { @Test void test() { long result = new ServiceAmbassador().doRemoteFunction(10); - assertTrue(result == 100 || result == RemoteServiceInterface.FAILURE); + assertTrue(result == 100 || result == RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue()); } } diff --git a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java index 830e66a2d..5dfe901e8 100644 --- a/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java +++ b/async-method-invocation/src/test/java/com/iluwatar/async/method/invocation/AppTest.java @@ -25,12 +25,24 @@ package com.iluwatar.async.method.invocation; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); + } } diff --git a/balking/src/test/java/com/iluwatar/balking/AppTest.java b/balking/src/test/java/com/iluwatar/balking/AppTest.java index 8c75a1f62..b12b6e1ec 100644 --- a/balking/src/test/java/com/iluwatar/balking/AppTest.java +++ b/balking/src/test/java/com/iluwatar/balking/AppTest.java @@ -24,15 +24,26 @@ package com.iluwatar.balking; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ class AppTest { + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - void main() { - App.main(); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow((Executable) App::main); } } \ No newline at end of file diff --git a/bridge/src/test/java/com/iluwatar/bridge/AppTest.java b/bridge/src/test/java/com/iluwatar/bridge/AppTest.java index d3edbb27c..026f0954c 100644 --- a/bridge/src/test/java/com/iluwatar/bridge/AppTest.java +++ b/bridge/src/test/java/com/iluwatar/bridge/AppTest.java @@ -25,12 +25,22 @@ package com.iluwatar.bridge; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/builder/src/test/java/com/iluwatar/builder/AppTest.java b/builder/src/test/java/com/iluwatar/builder/AppTest.java index 941f62f75..29b6ecb15 100644 --- a/builder/src/test/java/com/iluwatar/builder/AppTest.java +++ b/builder/src/test/java/com/iluwatar/builder/AppTest.java @@ -25,12 +25,23 @@ package com.iluwatar.builder; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java b/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java index 48e756acb..6c57e145e 100644 --- a/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java +++ b/business-delegate/src/test/java/com/iluwatar/business/delegate/AppTest.java @@ -27,13 +27,23 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Business Delegate example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - public void test() throws IOException { - String[] args = {}; - App.main(args); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/App.java b/bytecode/src/main/java/com/iluwatar/bytecode/App.java index 04f473cee..b85d8ef05 100644 --- a/bytecode/src/main/java/com/iluwatar/bytecode/App.java +++ b/bytecode/src/main/java/com/iluwatar/bytecode/App.java @@ -58,12 +58,14 @@ public class App { var vm = new VirtualMachine(); vm.getWizards()[0] = wizard; - interpretInstruction("LITERAL 0", vm); - interpretInstruction("LITERAL 0", vm); + String literal = "LITERAL 0"; + + interpretInstruction(literal, vm); + interpretInstruction(literal, vm); interpretInstruction("GET_HEALTH", vm); - interpretInstruction("LITERAL 0", vm); + interpretInstruction(literal, vm); interpretInstruction("GET_AGILITY", vm); - interpretInstruction("LITERAL 0", vm); + interpretInstruction(literal, vm); interpretInstruction("GET_WISDOM ", vm); interpretInstruction("ADD", vm); interpretInstruction("LITERAL 2", vm); diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java index 59962d39e..31060b683 100644 --- a/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java +++ b/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.bytecode; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/caching/src/test/java/com/iluwatar/caching/AppTest.java b/caching/src/test/java/com/iluwatar/caching/AppTest.java index 831cfe493..20a03282d 100644 --- a/caching/src/test/java/com/iluwatar/caching/AppTest.java +++ b/caching/src/test/java/com/iluwatar/caching/AppTest.java @@ -27,12 +27,23 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Caching example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/callback/src/test/java/com/iluwatar/callback/AppTest.java b/callback/src/test/java/com/iluwatar/callback/AppTest.java index c1f466dee..3a70df7e0 100644 --- a/callback/src/test/java/com/iluwatar/callback/AppTest.java +++ b/callback/src/test/java/com/iluwatar/callback/AppTest.java @@ -25,12 +25,23 @@ package com.iluwatar.callback; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Callback example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/chain/src/test/java/com/iluwatar/chain/AppTest.java b/chain/src/test/java/com/iluwatar/chain/AppTest.java index 164ff9bfe..6cd696517 100644 --- a/chain/src/test/java/com/iluwatar/chain/AppTest.java +++ b/chain/src/test/java/com/iluwatar/chain/AppTest.java @@ -25,13 +25,23 @@ package com.iluwatar.chain; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/combinator/pom.xml b/combinator/pom.xml index 3edfa7580..c2677fcc1 100644 --- a/combinator/pom.xml +++ b/combinator/pom.xml @@ -39,6 +39,12 @@ junit test + + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java index f42b46c14..6e7b4f63f 100644 --- a/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java +++ b/combinator/src/test/java/com/iluwatar/combinator/CombinatorAppTest.java @@ -25,12 +25,19 @@ package com.iluwatar.combinator; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; public class CombinatorAppTest { + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link CombinatorApp#main(String[])} + * throws an exception. + */ + @Test - public void main() { - CombinatorApp.main(new String[]{}); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> CombinatorApp.main(new String[]{})); } } \ No newline at end of file diff --git a/command/src/test/java/com/iluwatar/command/AppTest.java b/command/src/test/java/com/iluwatar/command/AppTest.java index cf691aba3..73d098fa3 100644 --- a/command/src/test/java/com/iluwatar/command/AppTest.java +++ b/command/src/test/java/com/iluwatar/command/AppTest.java @@ -25,12 +25,21 @@ package com.iluwatar.command; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Command example runs without errors. */ -public class AppTest { +class AppTest { + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/commander/src/main/java/com/iluwatar/commander/Commander.java b/commander/src/main/java/com/iluwatar/commander/Commander.java index 41779c076..c2e124663 100644 --- a/commander/src/main/java/com/iluwatar/commander/Commander.java +++ b/commander/src/main/java/com/iluwatar/commander/Commander.java @@ -39,6 +39,8 @@ import com.iluwatar.commander.shippingservice.ShippingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; + /** *

Commander pattern is used to handle all issues that can come up while making a * distributed transaction. The idea is to have a commander, which coordinates the execution of all @@ -159,8 +161,8 @@ public class Commander { private void sendPaymentRequest(Order order) { if (System.currentTimeMillis() - order.createdTime >= this.paymentTime) { - if (order.paid.equals(PaymentStatus.Trying)) { - order.paid = PaymentStatus.NotDone; + if (order.paid.equals(PaymentStatus.TRYING)) { + order.paid = PaymentStatus.NOT_DONE; sendPaymentFailureMessage(order); LOG.error("Order " + order.id + ": Payment time for order over, failed and returning.."); } //if succeeded or failed, would have been dequeued, no attempt to make payment @@ -169,53 +171,10 @@ public class Commander { var list = paymentService.exceptionsList; var t = new Thread(() -> { Retry.Operation op = (l) -> { - if (!l.isEmpty()) { - if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { - LOG.debug("Order " + order.id + ": Error in connecting to payment service," - + " trying again.."); - } else { - LOG.debug("Order " + order.id + ": Error in creating payment request.."); - } - throw l.remove(0); - } - if (order.paid.equals(PaymentStatus.Trying)) { - var transactionId = paymentService.receiveRequest(order.price); - order.paid = PaymentStatus.Done; - LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId); - if (!finalSiteMsgShown) { - LOG.info("Payment made successfully, thank you for shopping with us!!"); - finalSiteMsgShown = true; - } - sendSuccessMessage(order); - } + handlePaymentRetryOperation(order, l); }; Retry.HandleErrorIssue handleError = (o, err) -> { - if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) { - if (!finalSiteMsgShown) { - LOG.info("There was an error in payment. Your account/card details " - + "may have been incorrect. " - + "Meanwhile, your order has been converted to COD and will be shipped."); - finalSiteMsgShown = true; - } - LOG.error("Order " + order.id + ": Payment details incorrect, failed.."); - o.paid = PaymentStatus.NotDone; - sendPaymentFailureMessage(o); - } else { - if (o.messageSent.equals(MessageSent.NoneSent)) { - if (!finalSiteMsgShown) { - LOG.info("There was an error in payment. We are on it, and will get back to you " - + "asap. Don't worry, your order has been placed and will be shipped."); - finalSiteMsgShown = true; - } - LOG.warn("Order " + order.id + ": Payment error, going to queue.."); - sendPaymentPossibleErrorMsg(o); - } - if (o.paid.equals(PaymentStatus.Trying) && System - .currentTimeMillis() - o.createdTime < paymentTime) { - var qt = new QueueTask(o, TaskType.Payment, -1); - updateQueue(qt); - } - } + handlePaymentErrorIssue(order, o, err); }; var r = new Retry<>(op, handleError, numOfRetries, retryDuration, e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); @@ -228,18 +187,70 @@ public class Commander { t.start(); } + private void handlePaymentRetryOperation(Order order, List l) throws Exception { + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to payment service," + + " trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating payment request.."); + } + throw l.remove(0); + } + if (order.paid.equals(PaymentStatus.TRYING)) { + var transactionId = paymentService.receiveRequest(order.price); + order.paid = PaymentStatus.DONE; + LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId); + + if (!finalSiteMsgShown) { + LOG.info("Payment made successfully, thank you for shopping with us!!"); + finalSiteMsgShown = true; + } + sendSuccessMessage(order); + } + } + + private void handlePaymentErrorIssue(Order order, Order o, Exception err) { + if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) { + if (!finalSiteMsgShown) { + LOG.info("There was an error in payment. Your account/card details " + + "may have been incorrect. " + + "Meanwhile, your order has been converted to COD and will be shipped."); + finalSiteMsgShown = true; + } + LOG.error("Order " + order.id + ": Payment details incorrect, failed.."); + o.paid = PaymentStatus.NOT_DONE; + sendPaymentFailureMessage(o); + } else { + if (o.messageSent.equals(MessageSent.NONE_SENT)) { + if (!finalSiteMsgShown) { + LOG.info("There was an error in payment. We are on it, and will get back to you " + + "asap. Don't worry, your order has been placed and will be shipped."); + finalSiteMsgShown = true; + } + LOG.warn("Order " + order.id + ": Payment error, going to queue.."); + sendPaymentPossibleErrorMsg(o); + } + if (o.paid.equals(PaymentStatus.TRYING) && System + .currentTimeMillis() - o.createdTime < paymentTime) { + var qt = new QueueTask(o, TaskType.PAYMENT, -1); + updateQueue(qt); + } + } + } + private void updateQueue(QueueTask qt) { if (System.currentTimeMillis() - qt.order.createdTime >= this.queueTime) { // since payment time is lesser than queuetime it would have already failed.. // additional check not needed LOG.trace("Order " + qt.order.id + ": Queue time for order over, failed.."); return; - } else if (qt.taskType.equals(TaskType.Payment) && !qt.order.paid.equals(PaymentStatus.Trying) - || qt.taskType.equals(TaskType.Messaging) && (qt.messageType == 1 - && !qt.order.messageSent.equals(MessageSent.NoneSent) - || qt.order.messageSent.equals(MessageSent.PaymentFail) - || qt.order.messageSent.equals(MessageSent.PaymentSuccessful)) - || qt.taskType.equals(TaskType.EmployeeDb) && qt.order.addedToEmployeeHandle) { + } else if (qt.taskType.equals(TaskType.PAYMENT) && !qt.order.paid.equals(PaymentStatus.TRYING) + || qt.taskType.equals(TaskType.MESSAGING) && (qt.messageType == 1 + && !qt.order.messageSent.equals(MessageSent.NONE_SENT) + || qt.order.messageSent.equals(MessageSent.PAYMENT_FAIL) + || qt.order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) + || qt.taskType.equals(TaskType.EMPLOYEE_DB) && qt.order.addedToEmployeeHandle) { LOG.trace("Order " + qt.order.id + ": Not queueing task since task already done.."); return; } @@ -256,8 +267,8 @@ public class Commander { tryDoingTasksInQueue(); }; Retry.HandleErrorIssue handleError = (qt1, err) -> { - if (qt1.taskType.equals(TaskType.Payment)) { - qt1.order.paid = PaymentStatus.NotDone; + if (qt1.taskType.equals(TaskType.PAYMENT)) { + qt1.order.paid = PaymentStatus.NOT_DONE; sendPaymentFailureMessage(qt1.order); LOG.error("Order " + qt1.order.id + ": Unable to enqueue payment task," + " payment failed.."); @@ -331,7 +342,35 @@ public class Commander { } var list = messagingService.exceptionsList; Thread t = new Thread(() -> { - Retry.Operation op = (l) -> { + Retry.Operation op = handleSuccessMessageRetryOperation(order); + Retry.HandleErrorIssue handleError = (o, err) -> { + handleSuccessMessageErrorIssue(order, o); + }; + var r = new Retry<>(op, handleError, numOfRetries, retryDuration, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + try { + r.perform(list, order); + } catch (Exception e1) { + e1.printStackTrace(); + } + }); + t.start(); + } + + private void handleSuccessMessageErrorIssue(Order order, Order o) { + if ((o.messageSent.equals(MessageSent.NONE_SENT) || o.messageSent + .equals(MessageSent.PAYMENT_TRYING)) + && System.currentTimeMillis() - o.createdTime < messageTime) { + var qt = new QueueTask(order, TaskType.MESSAGING, 2); + updateQueue(qt); + LOG.info("Order " + order.id + ": Error in sending Payment Success message, trying to" + + " queue task and add to employee handle.."); + employeeHandleIssue(order); + } + } + + private Retry.Operation handleSuccessMessageRetryOperation(Order order) { + return (l) -> { if (!l.isEmpty()) { if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { LOG.debug("Order " + order.id + ": Error in connecting to messaging service " @@ -342,34 +381,14 @@ public class Commander { } throw l.remove(0); } - if (!order.messageSent.equals(MessageSent.PaymentFail) - && !order.messageSent.equals(MessageSent.PaymentSuccessful)) { + if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL) + && !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) { var requestId = messagingService.receiveRequest(2); - order.messageSent = MessageSent.PaymentSuccessful; + order.messageSent = MessageSent.PAYMENT_SUCCESSFUL; LOG.info("Order " + order.id + ": Payment Success message sent," + " request Id: " + requestId); } }; - Retry.HandleErrorIssue handleError = (o, err) -> { - if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent - .equals(MessageSent.PaymentTrying)) - && System.currentTimeMillis() - o.createdTime < messageTime) { - var qt = new QueueTask(order, TaskType.Messaging, 2); - updateQueue(qt); - LOG.info("Order " + order.id + ": Error in sending Payment Success message, trying to" - + " queue task and add to employee handle.."); - employeeHandleIssue(order); - } - }; - var r = new Retry<>(op, handleError, numOfRetries, retryDuration, - e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); - try { - r.perform(list, order); - } catch (Exception e1) { - e1.printStackTrace(); - } - }); - t.start(); } private void sendPaymentFailureMessage(Order order) { @@ -380,34 +399,10 @@ public class Commander { var list = messagingService.exceptionsList; var t = new Thread(() -> { Retry.Operation op = (l) -> { - if (!l.isEmpty()) { - if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { - LOG.debug("Order " + order.id + ": Error in connecting to messaging service " - + "(Payment Failure msg), trying again.."); - } else { - LOG.debug("Order " + order.id + ": Error in creating Payment Failure" - + " message request.."); - } - throw l.remove(0); - } - if (!order.messageSent.equals(MessageSent.PaymentFail) - && !order.messageSent.equals(MessageSent.PaymentSuccessful)) { - var requestId = messagingService.receiveRequest(0); - order.messageSent = MessageSent.PaymentFail; - LOG.info("Order " + order.id + ": Payment Failure message sent successfully," - + " request Id: " + requestId); - } + handlePaymentFailureRetryOperation(order, l); }; Retry.HandleErrorIssue handleError = (o, err) -> { - if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent - .equals(MessageSent.PaymentTrying)) - && System.currentTimeMillis() - o.createdTime < messageTime) { - var qt = new QueueTask(order, TaskType.Messaging, 0); - updateQueue(qt); - LOG.warn("Order " + order.id + ": Error in sending Payment Failure message, " - + "trying to queue task and add to employee handle.."); - employeeHandleIssue(o); - } + handlePaymentErrorIssue(order, o); }; var r = new Retry<>(op, handleError, numOfRetries, retryDuration, e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); @@ -420,6 +415,38 @@ public class Commander { t.start(); } + private void handlePaymentErrorIssue(Order order, Order o) { + if ((o.messageSent.equals(MessageSent.NONE_SENT) || o.messageSent + .equals(MessageSent.PAYMENT_TRYING)) + && System.currentTimeMillis() - o.createdTime < messageTime) { + var qt = new QueueTask(order, TaskType.MESSAGING, 0); + updateQueue(qt); + LOG.warn("Order " + order.id + ": Error in sending Payment Failure message, " + + "trying to queue task and add to employee handle.."); + employeeHandleIssue(o); + } + } + + private void handlePaymentFailureRetryOperation(Order order, List l) throws Exception { + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to messaging service " + + "(Payment Failure msg), trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating Payment Failure" + + " message request.."); + } + throw l.remove(0); + } + if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL) + && !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) { + var requestId = messagingService.receiveRequest(0); + order.messageSent = MessageSent.PAYMENT_FAIL; + LOG.info("Order " + order.id + ": Payment Failure message sent successfully," + + " request Id: " + requestId); + } + } + private void sendPaymentPossibleErrorMsg(Order order) { if (System.currentTimeMillis() - order.createdTime >= this.messageTime) { LOG.trace("Message time for order over, returning.."); @@ -428,34 +455,10 @@ public class Commander { var list = messagingService.exceptionsList; var t = new Thread(() -> { Retry.Operation op = (l) -> { - if (!l.isEmpty()) { - if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { - LOG.debug("Order " + order.id + ": Error in connecting to messaging service " - + "(Payment Error msg), trying again.."); - } else { - LOG.debug("Order " + order.id + ": Error in creating Payment Error" - + " messaging request.."); - } - throw l.remove(0); - } - if (order.paid.equals(PaymentStatus.Trying) && order.messageSent - .equals(MessageSent.NoneSent)) { - var requestId = messagingService.receiveRequest(1); - order.messageSent = MessageSent.PaymentTrying; - LOG.info("Order " + order.id + ": Payment Error message sent successfully," - + " request Id: " + requestId); - } + handlePaymentPossibleErrorMsgRetryOperation(order, l); }; Retry.HandleErrorIssue handleError = (o, err) -> { - if (o.messageSent.equals(MessageSent.NoneSent) && order.paid - .equals(PaymentStatus.Trying) - && System.currentTimeMillis() - o.createdTime < messageTime) { - var qt = new QueueTask(order, TaskType.Messaging, 1); - updateQueue(qt); - LOG.warn("Order " + order.id + ": Error in sending Payment Error message, " - + "trying to queue task and add to employee handle.."); - employeeHandleIssue(o); - } + handlePaymentPossibleErrorMsgErrorIssue(order, o); }; var r = new Retry<>(op, handleError, numOfRetries, retryDuration, e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); @@ -468,6 +471,38 @@ public class Commander { t.start(); } + private void handlePaymentPossibleErrorMsgErrorIssue(Order order, Order o) { + if (o.messageSent.equals(MessageSent.NONE_SENT) && order.paid + .equals(PaymentStatus.TRYING) + && System.currentTimeMillis() - o.createdTime < messageTime) { + var qt = new QueueTask(order, TaskType.MESSAGING, 1); + updateQueue(qt); + LOG.warn("Order " + order.id + ": Error in sending Payment Error message, " + + "trying to queue task and add to employee handle.."); + employeeHandleIssue(o); + } + } + + private void handlePaymentPossibleErrorMsgRetryOperation(Order order, List l) throws Exception { + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to messaging service " + + "(Payment Error msg), trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating Payment Error" + + " messaging request.."); + } + throw l.remove(0); + } + if (order.paid.equals(PaymentStatus.TRYING) && order.messageSent + .equals(MessageSent.NONE_SENT)) { + var requestId = messagingService.receiveRequest(1); + order.messageSent = MessageSent.PAYMENT_TRYING; + LOG.info("Order " + order.id + ": Payment Error message sent successfully," + + " request Id: " + requestId); + } + } + private void employeeHandleIssue(Order order) { if (System.currentTimeMillis() - order.createdTime >= this.employeeTime) { LOG.trace("Order " + order.id + ": Employee handle time for order over, returning.."); @@ -490,7 +525,7 @@ public class Commander { Retry.HandleErrorIssue handleError = (o, err) -> { if (!o.addedToEmployeeHandle && System .currentTimeMillis() - order.createdTime < employeeTime) { - var qt = new QueueTask(order, TaskType.EmployeeDb, -1); + var qt = new QueueTask(order, TaskType.EMPLOYEE_DB, -1); updateQueue(qt); LOG.warn("Order " + order.id + ": Error in adding to employee db," + " trying to queue task.."); @@ -520,21 +555,21 @@ public class Commander { LOG.trace("Order " + qt.order.id + ": This queue task of type " + qt.getType() + " does not need to be done anymore (timeout), dequeue.."); } else { - if (qt.taskType.equals(TaskType.Payment)) { - if (!qt.order.paid.equals(PaymentStatus.Trying)) { + if (qt.taskType.equals(TaskType.PAYMENT)) { + if (!qt.order.paid.equals(PaymentStatus.TRYING)) { tryDequeue(); LOG.trace("Order " + qt.order.id + ": This payment task already done, dequeueing.."); } else { sendPaymentRequest(qt.order); LOG.debug("Order " + qt.order.id + ": Trying to connect to payment service.."); } - } else if (qt.taskType.equals(TaskType.Messaging)) { - if (qt.order.messageSent.equals(MessageSent.PaymentFail) - || qt.order.messageSent.equals(MessageSent.PaymentSuccessful)) { + } else if (qt.taskType.equals(TaskType.MESSAGING)) { + if (qt.order.messageSent.equals(MessageSent.PAYMENT_FAIL) + || qt.order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) { tryDequeue(); LOG.trace("Order " + qt.order.id + ": This messaging task already done, dequeue.."); - } else if (qt.messageType == 1 && (!qt.order.messageSent.equals(MessageSent.NoneSent) - || !qt.order.paid.equals(PaymentStatus.Trying))) { + } else if (qt.messageType == 1 && (!qt.order.messageSent.equals(MessageSent.NONE_SENT) + || !qt.order.paid.equals(PaymentStatus.TRYING))) { tryDequeue(); LOG.trace("Order " + qt.order.id + ": This messaging task does not need to be done," + " dequeue.."); @@ -548,7 +583,7 @@ public class Commander { sendSuccessMessage(qt.order); LOG.debug("Order " + qt.order.id + ": Trying to connect to messaging service.."); } - } else if (qt.taskType.equals(TaskType.EmployeeDb)) { + } else if (qt.taskType.equals(TaskType.EMPLOYEE_DB)) { if (qt.order.addedToEmployeeHandle) { tryDequeue(); LOG.trace("Order " + qt.order.id + ": This employee handle task already done," diff --git a/commander/src/main/java/com/iluwatar/commander/Order.java b/commander/src/main/java/com/iluwatar/commander/Order.java index 87a9f794a..f736aa47c 100644 --- a/commander/src/main/java/com/iluwatar/commander/Order.java +++ b/commander/src/main/java/com/iluwatar/commander/Order.java @@ -33,11 +33,11 @@ import java.util.Random; public class Order { //can store all transactions ids also enum PaymentStatus { - NotDone, Trying, Done + NOT_DONE, TRYING, DONE } enum MessageSent { - NoneSent, PaymentFail, PaymentTrying, PaymentSuccessful + NONE_SENT, PAYMENT_FAIL, PAYMENT_TRYING, PAYMENT_SUCCESSFUL } final User user; @@ -65,8 +65,8 @@ public class Order { //can store all transactions ids also } this.id = id; USED_IDS.put(this.id, true); - this.paid = PaymentStatus.Trying; - this.messageSent = MessageSent.NoneSent; + this.paid = PaymentStatus.TRYING; + this.messageSent = MessageSent.NONE_SENT; this.addedToEmployeeHandle = false; } diff --git a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java index 3fb385757..e353a4c7c 100644 --- a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java +++ b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java @@ -38,7 +38,7 @@ public class MessagingService extends Service { private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class); enum MessageToSend { - PaymentFail, PaymentTrying, PaymentSuccessful + PAYMENT_FAIL, PAYMENT_TRYING, PAYMENT_SUCCESSFUL } class MessageRequest { @@ -63,11 +63,11 @@ public class MessagingService extends Service { var id = generateId(); MessageToSend msg; if (messageToSend == 0) { - msg = MessageToSend.PaymentFail; + msg = MessageToSend.PAYMENT_FAIL; } else if (messageToSend == 1) { - msg = MessageToSend.PaymentTrying; + msg = MessageToSend.PAYMENT_TRYING; } else { //messageToSend == 2 - msg = MessageToSend.PaymentSuccessful; + msg = MessageToSend.PAYMENT_SUCCESSFUL; } var req = new MessageRequest(id, msg); return updateDb(req); @@ -84,10 +84,10 @@ public class MessagingService extends Service { } String sendMessage(MessageToSend m) { - if (m.equals(MessageToSend.PaymentSuccessful)) { + if (m.equals(MessageToSend.PAYMENT_SUCCESSFUL)) { return "Msg: Your order has been placed and paid for successfully!" + " Thank you for shopping with us!"; - } else if (m.equals(MessageToSend.PaymentTrying)) { + } else if (m.equals(MessageToSend.PAYMENT_TRYING)) { return "Msg: There was an error in your payment process," + " we are working on it and will return back to you shortly." + " Meanwhile, your order has been placed and will be shipped."; diff --git a/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java b/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java index a27dd62b8..341eb628c 100644 --- a/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java +++ b/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java @@ -36,7 +36,7 @@ public class QueueTask { */ public enum TaskType { - Messaging, Payment, EmployeeDb + MESSAGING, PAYMENT, EMPLOYEE_DB } public Order order; @@ -68,7 +68,7 @@ public class QueueTask { * @return String representing type of task */ public String getType() { - if (!this.taskType.equals(TaskType.Messaging)) { + if (!this.taskType.equals(TaskType.MESSAGING)) { return this.taskType.toString(); } else { if (this.messageType == 0) { diff --git a/composite/src/test/java/com/iluwatar/composite/AppTest.java b/composite/src/test/java/com/iluwatar/composite/AppTest.java index 5eb8c35c7..c82056a51 100644 --- a/composite/src/test/java/com/iluwatar/composite/AppTest.java +++ b/composite/src/test/java/com/iluwatar/composite/AppTest.java @@ -23,15 +23,23 @@ package com.iluwatar.composite; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + Assertions.assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/converter/src/test/java/com/iluwatar/converter/AppTest.java b/converter/src/test/java/com/iluwatar/converter/AppTest.java index ed53c6863..7a99fe6ae 100644 --- a/converter/src/test/java/com/iluwatar/converter/AppTest.java +++ b/converter/src/test/java/com/iluwatar/converter/AppTest.java @@ -25,14 +25,24 @@ package com.iluwatar.converter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * App running test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void testMain() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/dao/src/test/java/com/iluwatar/dao/AppTest.java b/dao/src/test/java/com/iluwatar/dao/AppTest.java index edfcf7cd0..e6d41fc8a 100644 --- a/dao/src/test/java/com/iluwatar/dao/AppTest.java +++ b/dao/src/test/java/com/iluwatar/dao/AppTest.java @@ -25,12 +25,22 @@ package com.iluwatar.dao; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that DAO example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteDaoWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/AiComponent.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/AiComponent.java index 5b1be9e35..40acb2f71 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/AiComponent.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/AiComponent.java @@ -43,6 +43,6 @@ public class AiComponent implements Component { @Override public void render() { - + // Do Nothing. } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java index 616ebf801..1baf99a3a 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java @@ -40,7 +40,7 @@ public class AiComponentManager { private final int numEntities; - private static final Component[] AI_COMPONENTS = new AiComponent[MAX_ENTITIES]; + private final Component[] AI_COMPONENTS = new AiComponent[MAX_ENTITIES]; public AiComponentManager(int numEntities) { this.numEntities = numEntities; diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java index 61ba4ebdd..e5917979c 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java @@ -40,7 +40,7 @@ public class PhysicsComponentManager { private final int numEntities; - private static final Component[] PHYSICS_COMPONENTS = new PhysicsComponent[MAX_ENTITIES]; + private final Component[] PHYSICS_COMPONENTS = new PhysicsComponent[MAX_ENTITIES]; public PhysicsComponentManager(int numEntities) { this.numEntities = numEntities; diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java index f8c4b3522..b3522f908 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java @@ -40,7 +40,7 @@ public class RenderComponentManager { private final int numEntities; - private static final Component[] RENDER_COMPONENTS = new RenderComponent[MAX_ENTITIES]; + private final Component[] RENDER_COMPONENTS = new RenderComponent[MAX_ENTITIES]; public RenderComponentManager(int numEntities) { this.numEntities = numEntities; diff --git a/data-locality/src/test/java/com/iluwatar/data/locality/ApplicationTest.java b/data-locality/src/test/java/com/iluwatar/data/locality/ApplicationTest.java index 3371be4c1..b7d1f8961 100644 --- a/data-locality/src/test/java/com/iluwatar/data/locality/ApplicationTest.java +++ b/data-locality/src/test/java/com/iluwatar/data/locality/ApplicationTest.java @@ -26,16 +26,22 @@ package com.iluwatar.data.locality; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Test Game Application */ class ApplicationTest { /** - * Test run + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link Application#main(String[])} + * throws an exception. */ + @Test - void main() { - Application.main(new String[] {}); + void shouldExecuteGameApplicationWithoutException() { + assertDoesNotThrow(() -> Application.main(new String[] {})); } } \ No newline at end of file diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java index ec1d71be4..ab74edd6c 100644 --- a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java @@ -24,14 +24,25 @@ package com.iluwatar.datamapper; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; /** * Tests that Data-Mapper example runs without errors. */ -public final class AppTest { +final class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(); + void shouldExecuteApplicationWithoutException() { + + assertDoesNotThrow((Executable) App::main); } } diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java index 3a58d0c54..68a8b9444 100644 --- a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/AppTest.java @@ -25,9 +25,19 @@ package com.iluwatar.datatransfer; import org.junit.jupiter.api.Test; -public class AppTest { +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java index e8d4c8505..792d61233 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.decorator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java index 2865c76c1..8e20c9032 100644 --- a/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java +++ b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java @@ -25,14 +25,23 @@ package com.iluwatar.delegation.simple; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test Entry */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java index 51115496d..52508814a 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.dependency.injection; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/dirty-flag/src/test/java/org/dirty/flag/AppTest.java b/dirty-flag/src/test/java/org/dirty/flag/AppTest.java index 1b604898b..82c7fea9b 100644 --- a/dirty-flag/src/test/java/org/dirty/flag/AppTest.java +++ b/dirty-flag/src/test/java/org/dirty/flag/AppTest.java @@ -26,12 +26,22 @@ package org.dirty.flag; import com.iluwatar.dirtyflag.App; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Dirty-Flag example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index 084cbc8c9..cb66af1cb 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -44,6 +44,11 @@ org.apache.commons commons-lang3 + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java index eb89a4044..6612d2b00 100644 --- a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java @@ -25,14 +25,23 @@ package com.iluwatar.doublebuffer; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * App unit test. */ public class AppTest { + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void testMain() { - App.main(new String[]{}); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java index 6eac88fcd..e24e51094 100644 --- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java +++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java @@ -25,13 +25,23 @@ package com.iluwatar.doublechecked.locking; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java index 67ca00c56..e5df7a2be 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java @@ -25,13 +25,23 @@ package com.iluwatar.doubledispatch; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java b/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java index ed604e8c2..3da3b3e66 100644 --- a/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java +++ b/eip-aggregator/src/test/java/com/iluwatar/eip/aggregator/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.eip.aggregator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Test for App class */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void testMain() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java b/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java index 9f11c0209..14cdc5c65 100644 --- a/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java +++ b/eip-message-channel/src/test/java/com/iluwatar/eip/message/channel/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.eip.message.channel; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java b/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java index 107e954ed..f910d0abe 100644 --- a/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java +++ b/eip-publish-subscribe/src/test/java/com/iluwatar/eip/publish/subscribe/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.eip.publish.subscribe; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java b/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java index 1a7dfcb0a..d5936282e 100644 --- a/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java +++ b/eip-splitter/src/test/java/com/iluwatar/eip/splitter/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.eip.splitter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Test for App class */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void testMain() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java b/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java index 31154043c..8be8bcbe7 100644 --- a/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java +++ b/eip-wire-tap/src/test/java/com/iluwatar/eip/wiretap/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.eip.wiretap; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Test for App class */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void testMain() throws Exception { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/AppTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/AppTest.java index a65424023..e56bc9d7f 100644 --- a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/AppTest.java +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/AppTest.java @@ -25,13 +25,22 @@ package com.iluwatar.event.aggregator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/event-asynchronous/src/test/java/com/iluwatar/event/asynchronous/AppTest.java b/event-asynchronous/src/test/java/com/iluwatar/event/asynchronous/AppTest.java index 76554d6b1..638e77f87 100644 --- a/event-asynchronous/src/test/java/com/iluwatar/event/asynchronous/AppTest.java +++ b/event-asynchronous/src/test/java/com/iluwatar/event/asynchronous/AppTest.java @@ -25,12 +25,22 @@ package com.iluwatar.event.asynchronous; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that EventAsynchronous example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/event-driven-architecture/src/test/java/com/iluwatar/eda/AppTest.java b/event-driven-architecture/src/test/java/com/iluwatar/eda/AppTest.java index 0f1720363..eb944a22c 100644 --- a/event-driven-architecture/src/test/java/com/iluwatar/eda/AppTest.java +++ b/event-driven-architecture/src/test/java/com/iluwatar/eda/AppTest.java @@ -25,12 +25,22 @@ package com.iluwatar.eda; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Event Driven Architecture example runs without errors. */ -public class AppTest { +class AppTest { + + /** + * Issue: Add at least one assertion to this test case. + * + * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} + * throws an exception. + */ + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/execute-around/src/test/java/com/iluwatar/execute/around/AppTest.java b/execute-around/src/test/java/com/iluwatar/execute/around/AppTest.java index 5512ba8d2..6516ede4a 100644 --- a/execute-around/src/test/java/com/iluwatar/execute/around/AppTest.java +++ b/execute-around/src/test/java/com/iluwatar/execute/around/AppTest.java @@ -29,19 +29,21 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests execute-around example. */ -public class AppTest { +class AppTest { @Test - public void test() throws IOException { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } @BeforeEach @AfterEach - public void cleanup() { + void cleanup() { var file = new File("testfile.txt"); file.delete(); } diff --git a/extension-objects/src/main/java/concreteextensions/Commander.java b/extension-objects/src/main/java/concreteextensions/Commander.java index 1d8054562..ffd46dd25 100644 --- a/extension-objects/src/main/java/concreteextensions/Commander.java +++ b/extension-objects/src/main/java/concreteextensions/Commander.java @@ -45,4 +45,8 @@ public class Commander implements CommanderExtension { public void commanderReady() { LOGGER.info("[Commander] " + unit.getName() + " is ready!"); } + + public CommanderUnit getUnit() { + return unit; + } } diff --git a/extension-objects/src/main/java/concreteextensions/Sergeant.java b/extension-objects/src/main/java/concreteextensions/Sergeant.java index 4f5a474b3..aea2ddaca 100644 --- a/extension-objects/src/main/java/concreteextensions/Sergeant.java +++ b/extension-objects/src/main/java/concreteextensions/Sergeant.java @@ -43,6 +43,10 @@ public class Sergeant implements SergeantExtension { @Override public void sergeantReady() { - LOGGER.info("[Sergeant] " + unit.getName() + " is ready! "); + LOGGER.info("[Sergeant] " + unit.getName() + " is ready!"); + } + + public SergeantUnit getUnit() { + return unit; } } diff --git a/extension-objects/src/main/java/concreteextensions/Soldier.java b/extension-objects/src/main/java/concreteextensions/Soldier.java index d500ab604..76ddbfd06 100644 --- a/extension-objects/src/main/java/concreteextensions/Soldier.java +++ b/extension-objects/src/main/java/concreteextensions/Soldier.java @@ -44,4 +44,8 @@ public class Soldier implements SoldierExtension { public void soldierReady() { LOGGER.info("[Solider] " + unit.getName() + " is ready!"); } + + public SoldierUnit getUnit() { + return unit; + } } diff --git a/extension-objects/src/test/java/AppTest.java b/extension-objects/src/test/java/AppTest.java index 2af33e506..321bf758f 100644 --- a/extension-objects/src/test/java/AppTest.java +++ b/extension-objects/src/test/java/AppTest.java @@ -23,13 +23,16 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Created by Srdjan on 03-May-17. */ -public class AppTest { +class AppTest { + @Test - public void main() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/extension-objects/src/test/java/concreteextensions/CommanderTest.java b/extension-objects/src/test/java/concreteextensions/CommanderTest.java index 60ff614e4..0c9d00baf 100644 --- a/extension-objects/src/test/java/concreteextensions/CommanderTest.java +++ b/extension-objects/src/test/java/concreteextensions/CommanderTest.java @@ -23,17 +23,43 @@ package concreteextensions; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; import units.CommanderUnit; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Created by Srdjan on 03-May-17. + * + * Modified by ToxicDreamz on 15-Aug-20 */ -public class CommanderTest { +class CommanderTest { + @Test - public void commanderReady() { + void shouldExecuteCommanderReady() { + + Logger commanderLogger = (Logger) LoggerFactory.getLogger(Commander.class); + + ListAppender listAppender = new ListAppender<>(); + listAppender.start(); + + commanderLogger.addAppender(listAppender); + final var commander = new Commander(new CommanderUnit("CommanderUnitTest")); commander.commanderReady(); + + List logsList = listAppender.list; + assertEquals("[Commander] " + commander.getUnit().getName() + " is ready!", logsList.get(0) + .getMessage()); + assertEquals(Level.INFO, logsList.get(0) + .getLevel()); } } \ No newline at end of file diff --git a/extension-objects/src/test/java/concreteextensions/SergeantTest.java b/extension-objects/src/test/java/concreteextensions/SergeantTest.java index a5a60d914..3970a5c80 100644 --- a/extension-objects/src/test/java/concreteextensions/SergeantTest.java +++ b/extension-objects/src/test/java/concreteextensions/SergeantTest.java @@ -23,17 +23,41 @@ package concreteextensions; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; import units.SergeantUnit; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Created by Srdjan on 03-May-17. */ -public class SergeantTest { +class SergeantTest { + @Test - public void sergeantReady() { + void sergeantReady() { + + Logger sergeantLogger = (Logger) LoggerFactory.getLogger(Sergeant.class); + + ListAppender listAppender = new ListAppender<>(); + listAppender.start(); + + sergeantLogger.addAppender(listAppender); + final var sergeant = new Sergeant(new SergeantUnit("SergeantUnitTest")); sergeant.sergeantReady(); + + List logsList = listAppender.list; + assertEquals("[Sergeant] " + sergeant.getUnit().getName() + " is ready!", logsList.get(0) + .getMessage()); + assertEquals(Level.INFO, logsList.get(0) + .getLevel()); } } \ No newline at end of file diff --git a/extension-objects/src/test/java/concreteextensions/SoldierTest.java b/extension-objects/src/test/java/concreteextensions/SoldierTest.java index 89c8c2d91..98224e848 100644 --- a/extension-objects/src/test/java/concreteextensions/SoldierTest.java +++ b/extension-objects/src/test/java/concreteextensions/SoldierTest.java @@ -23,17 +23,41 @@ package concreteextensions; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; import units.SoldierUnit; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Created by Srdjan on 03-May-17. */ -public class SoldierTest { +class SoldierTest { + @Test - public void soldierReady() { + void soldierReady() { + + Logger soldierLogger = (Logger) LoggerFactory.getLogger(Soldier.class); + + ListAppender listAppender = new ListAppender<>(); + listAppender.start(); + + soldierLogger.addAppender(listAppender); + final var soldier = new Soldier(new SoldierUnit("SoldierUnitTest")); soldier.soldierReady(); + + List logsList = listAppender.list; + assertEquals("[Soldier] " + soldier.getUnit().getName() + " is ready!", logsList.get(0) + .getMessage()); + assertEquals(Level.INFO, logsList.get(0) + .getLevel()); } } \ No newline at end of file diff --git a/facade/src/test/java/com/iluwatar/facade/AppTest.java b/facade/src/test/java/com/iluwatar/facade/AppTest.java index b6287b02b..7e2d389dc 100644 --- a/facade/src/test/java/com/iluwatar/facade/AppTest.java +++ b/facade/src/test/java/com/iluwatar/facade/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.facade; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/factory-kit/src/test/java/com/iluwatar/factorykit/app/AppTest.java b/factory-kit/src/test/java/com/iluwatar/factorykit/app/AppTest.java index f1d3c65a2..99477aaf0 100644 --- a/factory-kit/src/test/java/com/iluwatar/factorykit/app/AppTest.java +++ b/factory-kit/src/test/java/com/iluwatar/factorykit/app/AppTest.java @@ -26,14 +26,16 @@ package com.iluwatar.factorykit.app; import com.iluwatar.factorykit.App; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test Entrypoint */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/factory-method/src/test/java/com/iluwatar/factory/method/AppTest.java b/factory-method/src/test/java/com/iluwatar/factory/method/AppTest.java index c23295d9a..8756ba0aa 100644 --- a/factory-method/src/test/java/com/iluwatar/factory/method/AppTest.java +++ b/factory-method/src/test/java/com/iluwatar/factory/method/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.factory.method; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Factory Method example runs without errors. */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/app/AppTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/app/AppTest.java index 6f25d8416..1b6671917 100644 --- a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/app/AppTest.java +++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/app/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.fluentinterface.app; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test Entry */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java index 27d374f5d..c43d87680 100644 --- a/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java +++ b/flux/src/main/java/com/iluwatar/flux/dispatcher/Dispatcher.java @@ -57,15 +57,10 @@ public final class Dispatcher { */ public void menuItemSelected(MenuItem menuItem) { dispatchAction(new MenuAction(menuItem)); - switch (menuItem) { - case HOME: - case PRODUCTS: - default: - dispatchAction(new ContentAction(Content.PRODUCTS)); - break; - case COMPANY: - dispatchAction(new ContentAction(Content.COMPANY)); - break; + if (menuItem == MenuItem.COMPANY) { + dispatchAction(new ContentAction(Content.COMPANY)); + } else { + dispatchAction(new ContentAction(Content.PRODUCTS)); } } diff --git a/flux/src/test/java/com/iluwatar/flux/app/AppTest.java b/flux/src/test/java/com/iluwatar/flux/app/AppTest.java index 8916ad4de..649708d8f 100644 --- a/flux/src/test/java/com/iluwatar/flux/app/AppTest.java +++ b/flux/src/test/java/com/iluwatar/flux/app/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.flux.app; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/flyweight/src/test/java/com/iluwatar/flyweight/AppTest.java b/flyweight/src/test/java/com/iluwatar/flyweight/AppTest.java index 3d81a6db2..5f957c794 100644 --- a/flyweight/src/test/java/com/iluwatar/flyweight/AppTest.java +++ b/flyweight/src/test/java/com/iluwatar/flyweight/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.flyweight; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java index 2ea58c6a6..cf33bfb48 100644 --- a/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java +++ b/front-controller/src/test/java/com/iluwatar/front/controller/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.front.controller; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/game-loop/pom.xml b/game-loop/pom.xml index 2c2908271..706d3cff4 100644 --- a/game-loop/pom.xml +++ b/game-loop/pom.xml @@ -39,6 +39,12 @@ junit junit + + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/game-loop/src/test/java/com/iluwatar/gameloop/AppTest.java b/game-loop/src/test/java/com/iluwatar/gameloop/AppTest.java index 447e4f411..0c027028d 100644 --- a/game-loop/src/test/java/com/iluwatar/gameloop/AppTest.java +++ b/game-loop/src/test/java/com/iluwatar/gameloop/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.gameloop; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * App unit test class. */ public class AppTest { @Test - public void testMain() { - new App().main(new String[]{}); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java index b3cf4839b..395599927 100644 --- a/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java +++ b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.halfsynchalfasync; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(null); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(null)); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java index 96ab74ba3..6d6c33239 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java @@ -46,6 +46,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { private static final String DEFAULT_DB = "lotteryDB"; private static final String DEFAULT_TICKETS_COLLECTION = "lotteryTickets"; private static final String DEFAULT_COUNTERS_COLLECTION = "counters"; + private static final String TICKET_ID = "ticketId"; private MongoClient mongoClient; private MongoDatabase database; @@ -93,7 +94,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { } private void initCounters() { - var doc = new Document("_id", "ticketId").append("seq", 1); + var doc = new Document("_id", TICKET_ID).append("seq", 1); countersCollection.insertOne(doc); } @@ -103,7 +104,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { * @return next ticket id */ public int getNextId() { - var find = new Document("_id", "ticketId"); + var find = new Document("_id", TICKET_ID); var increase = new Document("seq", 1); var update = new Document("$inc", increase); var result = countersCollection.findOneAndUpdate(find, update); @@ -131,7 +132,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { @Override public Optional findById(LotteryTicketId id) { return ticketsCollection - .find(new Document("ticketId", id.getId())) + .find(new Document(TICKET_ID, id.getId())) .limit(1) .into(new ArrayList<>()) .stream() @@ -142,7 +143,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { @Override public Optional save(LotteryTicket ticket) { var ticketId = getNextId(); - var doc = new Document("ticketId", ticketId); + var doc = new Document(TICKET_ID, ticketId); doc.put("email", ticket.getPlayerDetails().getEmail()); doc.put("bank", ticket.getPlayerDetails().getBankAccount()); doc.put("phone", ticket.getPlayerDetails().getPhoneNumber()); @@ -173,7 +174,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { .map(Integer::parseInt) .collect(Collectors.toSet()); var lotteryNumbers = LotteryNumbers.create(numbers); - var ticketId = new LotteryTicketId(doc.getInteger("ticketId")); + var ticketId = new LotteryTicketId(doc.getInteger(TICKET_ID)); return new LotteryTicket(ticketId, playerDetails, lotteryNumbers); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java index c632debe8..62fcf32b4 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java @@ -36,6 +36,9 @@ public class MongoEventLog implements LotteryEventLog { private static final String DEFAULT_DB = "lotteryDB"; private static final String DEFAULT_EVENTS_COLLECTION = "events"; + private static final String EMAIL = "email"; + private static final String PHONE = "phone"; + public static final String MESSAGE = "message"; private MongoClient mongoClient; private MongoDatabase database; @@ -107,41 +110,41 @@ public class MongoEventLog implements LotteryEventLog { @Override public void ticketSubmitted(PlayerDetails details) { - var document = new Document("email", details.getEmail()); - document.put("phone", details.getPhoneNumber()); + var document = new Document(EMAIL, details.getEmail()); + document.put(PHONE, details.getPhoneNumber()); document.put("bank", details.getBankAccount()); document - .put("message", "Lottery ticket was submitted and bank account was charged for 3 credits."); + .put(MESSAGE, "Lottery ticket was submitted and bank account was charged for 3 credits."); eventsCollection.insertOne(document); stdOutEventLog.ticketSubmitted(details); } @Override public void ticketSubmitError(PlayerDetails details) { - var document = new Document("email", details.getEmail()); - document.put("phone", details.getPhoneNumber()); + var document = new Document(EMAIL, details.getEmail()); + document.put(PHONE, details.getPhoneNumber()); document.put("bank", details.getBankAccount()); - document.put("message", "Lottery ticket could not be submitted because lack of funds."); + document.put(MESSAGE, "Lottery ticket could not be submitted because lack of funds."); eventsCollection.insertOne(document); stdOutEventLog.ticketSubmitError(details); } @Override public void ticketDidNotWin(PlayerDetails details) { - var document = new Document("email", details.getEmail()); - document.put("phone", details.getPhoneNumber()); + var document = new Document(EMAIL, details.getEmail()); + document.put(PHONE, details.getPhoneNumber()); document.put("bank", details.getBankAccount()); - document.put("message", "Lottery ticket was checked and unfortunately did not win this time."); + document.put(MESSAGE, "Lottery ticket was checked and unfortunately did not win this time."); eventsCollection.insertOne(document); stdOutEventLog.ticketDidNotWin(details); } @Override public void ticketWon(PlayerDetails details, int prizeAmount) { - var document = new Document("email", details.getEmail()); - document.put("phone", details.getPhoneNumber()); + var document = new Document(EMAIL, details.getEmail()); + document.put(PHONE, details.getPhoneNumber()); document.put("bank", details.getBankAccount()); - document.put("message", String + document.put(MESSAGE, String .format("Lottery ticket won! The bank account was deposited with %d credits.", prizeAmount)); eventsCollection.insertOne(document); @@ -150,10 +153,10 @@ public class MongoEventLog implements LotteryEventLog { @Override public void prizeError(PlayerDetails details, int prizeAmount) { - var document = new Document("email", details.getEmail()); - document.put("phone", details.getPhoneNumber()); + var document = new Document(EMAIL, details.getEmail()); + document.put(PHONE, details.getPhoneNumber()); document.put("bank", details.getBankAccount()); - document.put("message", String + document.put(MESSAGE, String .format("Lottery ticket won! Unfortunately the bank credit transfer of %d failed.", prizeAmount)); eventsCollection.insertOne(document); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java index 05d51a283..d2ad89c9b 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/AppTest.java @@ -25,13 +25,16 @@ package com.iluwatar.hexagonal; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Unit test for simple App. */ class AppTest { @Test - void testApp() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); + } } diff --git a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/AppTest.java b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/AppTest.java index 8fbe9f1d2..d8f22a478 100644 --- a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/AppTest.java +++ b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.intercepting.filter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test. */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/AppTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/AppTest.java index 505dc559c..f4fb45637 100644 --- a/interpreter/src/test/java/com/iluwatar/interpreter/AppTest.java +++ b/interpreter/src/test/java/com/iluwatar/interpreter/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.interpreter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java index ccb33307c..2e0d28b67 100644 --- a/iterator/src/test/java/com/iluwatar/iterator/AppTest.java +++ b/iterator/src/test/java/com/iluwatar/iterator/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.iterator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test */ class AppTest { @Test - void testApp() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/layers/src/main/java/com/iluwatar/layers/app/App.java b/layers/src/main/java/com/iluwatar/layers/app/App.java index e5a4f9995..8574b8d02 100644 --- a/layers/src/main/java/com/iluwatar/layers/app/App.java +++ b/layers/src/main/java/com/iluwatar/layers/app/App.java @@ -81,6 +81,7 @@ import java.util.List; public class App { private static final CakeBakingService cakeBakingService = new CakeBakingServiceImpl(); + public static final String STRAWBERRY = "strawberry"; /** * Application entry point. @@ -103,10 +104,10 @@ public class App { private static void initializeData(CakeBakingService cakeBakingService) { cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200)); cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900)); - cakeBakingService.saveNewLayer(new CakeLayerInfo("strawberry", 950)); + cakeBakingService.saveNewLayer(new CakeLayerInfo(STRAWBERRY, 950)); cakeBakingService.saveNewLayer(new CakeLayerInfo("lemon", 950)); cakeBakingService.saveNewLayer(new CakeLayerInfo("vanilla", 950)); - cakeBakingService.saveNewLayer(new CakeLayerInfo("strawberry", 950)); + cakeBakingService.saveNewLayer(new CakeLayerInfo(STRAWBERRY, 950)); cakeBakingService.saveNewTopping(new CakeToppingInfo("candies", 350)); cakeBakingService.saveNewTopping(new CakeToppingInfo("cherry", 350)); @@ -114,7 +115,7 @@ public class App { var cake1 = new CakeInfo(new CakeToppingInfo("candies", 0), List.of( new CakeLayerInfo("chocolate", 0), new CakeLayerInfo("banana", 0), - new CakeLayerInfo("strawberry", 0))); + new CakeLayerInfo(STRAWBERRY, 0))); try { cakeBakingService.bakeNewCake(cake1); } catch (CakeBakingException e) { @@ -123,7 +124,7 @@ public class App { var cake2 = new CakeInfo(new CakeToppingInfo("cherry", 0), List.of( new CakeLayerInfo("vanilla", 0), new CakeLayerInfo("lemon", 0), - new CakeLayerInfo("strawberry", 0))); + new CakeLayerInfo(STRAWBERRY, 0))); try { cakeBakingService.bakeNewCake(cake2); } catch (CakeBakingException e) { diff --git a/layers/src/test/java/com/iluwatar/layers/app/AppTest.java b/layers/src/test/java/com/iluwatar/layers/app/AppTest.java index 10d224a8e..105487683 100644 --- a/layers/src/test/java/com/iluwatar/layers/app/AppTest.java +++ b/layers/src/test/java/com/iluwatar/layers/app/AppTest.java @@ -23,19 +23,19 @@ package com.iluwatar.layers.app; -import com.iluwatar.layers.app.App; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * * Application test * */ -public class AppTest { +class AppTest { @Test - public void test() { - String[] args = {}; - App.main(args); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AppTest.java b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AppTest.java index eeccd10ce..74c324b24 100644 --- a/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AppTest.java +++ b/lazy-loading/src/test/java/com/iluwatar/lazy/loading/AppTest.java @@ -25,16 +25,17 @@ package com.iluwatar.lazy.loading; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * * Application test * */ -public class AppTest { +class AppTest { @Test - public void test() { - String[] args = {}; - App.main(args); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/leader-election/src/main/java/com/iluwatar/leaderelection/AbstractInstance.java b/leader-election/src/main/java/com/iluwatar/leaderelection/AbstractInstance.java index f30610597..94db89ef7 100644 --- a/leader-election/src/main/java/com/iluwatar/leaderelection/AbstractInstance.java +++ b/leader-election/src/main/java/com/iluwatar/leaderelection/AbstractInstance.java @@ -36,6 +36,7 @@ public abstract class AbstractInstance implements Instance, Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractInstance.class); protected static final int HEARTBEAT_INTERVAL = 5000; + private static final String INSTANCE = "Instance "; protected MessageManager messageManager; protected Queue messageQueue; @@ -106,27 +107,27 @@ public abstract class AbstractInstance implements Instance, Runnable { private void processMessage(Message message) { switch (message.getType()) { case ELECTION: - LOGGER.info("Instance " + localId + " - Election Message handling..."); + LOGGER.info(INSTANCE + localId + " - Election Message handling..."); handleElectionMessage(message); break; case LEADER: - LOGGER.info("Instance " + localId + " - Leader Message handling..."); + LOGGER.info(INSTANCE + localId + " - Leader Message handling..."); handleLeaderMessage(message); break; case HEARTBEAT: - LOGGER.info("Instance " + localId + " - Heartbeat Message handling..."); + LOGGER.info(INSTANCE + localId + " - Heartbeat Message handling..."); handleHeartbeatMessage(message); break; case ELECTION_INVOKE: - LOGGER.info("Instance " + localId + " - Election Invoke Message handling..."); + LOGGER.info(INSTANCE + localId + " - Election Invoke Message handling..."); handleElectionInvokeMessage(); break; case LEADER_INVOKE: - LOGGER.info("Instance " + localId + " - Leader Invoke Message handling..."); + LOGGER.info(INSTANCE + localId + " - Leader Invoke Message handling..."); handleLeaderInvokeMessage(); break; case HEARTBEAT_INVOKE: - LOGGER.info("Instance " + localId + " - Heartbeat Invoke Message handling..."); + LOGGER.info(INSTANCE + localId + " - Heartbeat Invoke Message handling..."); handleHeartbeatInvokeMessage(); break; default: diff --git a/leader-election/src/main/java/com/iluwatar/leaderelection/bully/BullyInstance.java b/leader-election/src/main/java/com/iluwatar/leaderelection/bully/BullyInstance.java index 92cb18ab4..3181791d4 100644 --- a/leader-election/src/main/java/com/iluwatar/leaderelection/bully/BullyInstance.java +++ b/leader-election/src/main/java/com/iluwatar/leaderelection/bully/BullyInstance.java @@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory; public class BullyInstance extends AbstractInstance { private static final Logger LOGGER = LoggerFactory.getLogger(BullyInstance.class); + private static final String INSTANCE = "Instance "; /** * Constructor of BullyInstance. @@ -59,20 +60,20 @@ public class BullyInstance extends AbstractInstance { try { boolean isLeaderAlive = messageManager.sendHeartbeatMessage(leaderId); if (isLeaderAlive) { - LOGGER.info("Instance " + localId + "- Leader is alive."); + LOGGER.info(INSTANCE + localId + "- Leader is alive."); Thread.sleep(HEARTBEAT_INTERVAL); messageManager.sendHeartbeatInvokeMessage(localId); } else { - LOGGER.info("Instance " + localId + "- Leader is not alive. Start election."); + LOGGER.info(INSTANCE + localId + "- Leader is not alive. Start election."); boolean electionResult = messageManager.sendElectionMessage(localId, String.valueOf(localId)); if (electionResult) { - LOGGER.info("Instance " + localId + "- Succeed in election. Start leader notification."); + LOGGER.info(INSTANCE + localId + "- Succeed in election. Start leader notification."); messageManager.sendLeaderMessage(localId, localId); } } } catch (InterruptedException e) { - LOGGER.info("Instance " + localId + "- Interrupted."); + LOGGER.info(INSTANCE + localId + "- Interrupted."); } } @@ -84,10 +85,10 @@ public class BullyInstance extends AbstractInstance { @Override protected void handleElectionInvokeMessage() { if (!isLeader()) { - LOGGER.info("Instance " + localId + "- Start election."); + LOGGER.info(INSTANCE + localId + "- Start election."); boolean electionResult = messageManager.sendElectionMessage(localId, String.valueOf(localId)); if (electionResult) { - LOGGER.info("Instance " + localId + "- Succeed in election. Start leader notification."); + LOGGER.info(INSTANCE + localId + "- Succeed in election. Start leader notification."); leaderId = localId; messageManager.sendLeaderMessage(localId, localId); messageManager.sendHeartbeatInvokeMessage(localId); @@ -101,25 +102,25 @@ public class BullyInstance extends AbstractInstance { @Override protected void handleLeaderMessage(Message message) { leaderId = Integer.valueOf(message.getContent()); - LOGGER.info("Instance " + localId + " - Leader update done."); + LOGGER.info(INSTANCE + localId + " - Leader update done."); } private boolean isLeader() { return localId == leaderId; } - /** - * Not used in Bully instance. - */ @Override protected void handleLeaderInvokeMessage() { + // Not used in Bully Instance } @Override protected void handleHeartbeatMessage(Message message) { + // Not used in Bully Instance } @Override protected void handleElectionMessage(Message message) { + // Not used in Bully Instance } } diff --git a/leader-election/src/main/java/com/iluwatar/leaderelection/ring/RingInstance.java b/leader-election/src/main/java/com/iluwatar/leaderelection/ring/RingInstance.java index d4a3075d8..2d2d0ae1a 100644 --- a/leader-election/src/main/java/com/iluwatar/leaderelection/ring/RingInstance.java +++ b/leader-election/src/main/java/com/iluwatar/leaderelection/ring/RingInstance.java @@ -46,6 +46,7 @@ import org.slf4j.LoggerFactory; public class RingInstance extends AbstractInstance { private static final Logger LOGGER = LoggerFactory.getLogger(RingInstance.class); + private static final String INSTANCE = "Instance "; /** * Constructor of RingInstance. @@ -64,15 +65,15 @@ public class RingInstance extends AbstractInstance { try { var isLeaderAlive = messageManager.sendHeartbeatMessage(this.leaderId); if (isLeaderAlive) { - LOGGER.info("Instance " + localId + "- Leader is alive. Start next heartbeat in 5 second."); + LOGGER.info(INSTANCE + localId + "- Leader is alive. Start next heartbeat in 5 second."); Thread.sleep(HEARTBEAT_INTERVAL); messageManager.sendHeartbeatInvokeMessage(this.localId); } else { - LOGGER.info("Instance " + localId + "- Leader is not alive. Start election."); + LOGGER.info(INSTANCE + localId + "- Leader is not alive. Start election."); messageManager.sendElectionMessage(this.localId, String.valueOf(this.localId)); } } catch (InterruptedException e) { - LOGGER.info("Instance " + localId + "- Interrupted."); + LOGGER.info(INSTANCE + localId + "- Interrupted."); } } @@ -85,14 +86,14 @@ public class RingInstance extends AbstractInstance { @Override protected void handleElectionMessage(Message message) { var content = message.getContent(); - LOGGER.info("Instance " + localId + " - Election Message: " + content); + LOGGER.info(INSTANCE + localId + " - Election Message: " + content); var candidateList = Arrays.stream(content.trim().split(",")) .map(Integer::valueOf) .sorted() .collect(Collectors.toList()); if (candidateList.contains(localId)) { var newLeaderId = candidateList.get(0); - LOGGER.info("Instance " + localId + " - New leader should be " + newLeaderId + "."); + LOGGER.info(INSTANCE + localId + " - New leader should be " + newLeaderId + "."); messageManager.sendLeaderMessage(localId, newLeaderId); } else { content += "," + localId; @@ -108,11 +109,11 @@ public class RingInstance extends AbstractInstance { protected void handleLeaderMessage(Message message) { var newLeaderId = Integer.valueOf(message.getContent()); if (this.leaderId != newLeaderId) { - LOGGER.info("Instance " + localId + " - Update leaderID"); + LOGGER.info(INSTANCE + localId + " - Update leaderID"); this.leaderId = newLeaderId; messageManager.sendLeaderMessage(localId, newLeaderId); } else { - LOGGER.info("Instance " + localId + " - Leader update done. Start heartbeat."); + LOGGER.info(INSTANCE + localId + " - Leader update done. Start heartbeat."); messageManager.sendHeartbeatInvokeMessage(localId); } } @@ -122,14 +123,17 @@ public class RingInstance extends AbstractInstance { */ @Override protected void handleLeaderInvokeMessage() { + // Not used in Ring instance. } @Override protected void handleHeartbeatMessage(Message message) { + // Not used in Ring instance. } @Override protected void handleElectionInvokeMessage() { + // Not used in Ring instance. } } diff --git a/leader-election/src/test/java/com/iluwatar/leaderelection/bully/BullyAppTest.java b/leader-election/src/test/java/com/iluwatar/leaderelection/bully/BullyAppTest.java index 3ef36f758..19497a32c 100644 --- a/leader-election/src/test/java/com/iluwatar/leaderelection/bully/BullyAppTest.java +++ b/leader-election/src/test/java/com/iluwatar/leaderelection/bully/BullyAppTest.java @@ -25,15 +25,16 @@ package com.iluwatar.leaderelection.bully; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * BullyApp unit test. */ -public class BullyAppTest { +class BullyAppTest { @Test - public void test() { - String[] args = {}; - BullyApp.main(args); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> BullyApp.main(new String[]{})); } } diff --git a/leader-election/src/test/java/com/iluwatar/leaderelection/ring/RingAppTest.java b/leader-election/src/test/java/com/iluwatar/leaderelection/ring/RingAppTest.java index ec3851d9b..ce5c59aa7 100644 --- a/leader-election/src/test/java/com/iluwatar/leaderelection/ring/RingAppTest.java +++ b/leader-election/src/test/java/com/iluwatar/leaderelection/ring/RingAppTest.java @@ -25,15 +25,16 @@ package com.iluwatar.leaderelection.ring; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * RingApp unit test. */ -public class RingAppTest { +class RingAppTest { @Test - public void test() { - String[] args = {}; - RingApp.main(args); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> RingApp.main(new String[]{})); } } diff --git a/leader-followers/pom.xml b/leader-followers/pom.xml index 4efdbf3ac..c0f27d051 100644 --- a/leader-followers/pom.xml +++ b/leader-followers/pom.xml @@ -37,6 +37,11 @@ junit test + + org.junit.jupiter + junit-jupiter-engine + test + org.mockito mockito-core diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/App.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/App.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/App.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/App.java diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/Task.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/Task.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/Task.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/Task.java diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskHandler.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/TaskHandler.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskHandler.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/TaskHandler.java diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/TaskSet.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/TaskSet.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/TaskSet.java diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/WorkCenter.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/WorkCenter.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/WorkCenter.java diff --git a/leader-followers/src/main/java/com.iluwatar.leaderfollowers/Worker.java b/leader-followers/src/main/java/com/iluwatar/leaderfollowers/Worker.java similarity index 100% rename from leader-followers/src/main/java/com.iluwatar.leaderfollowers/Worker.java rename to leader-followers/src/main/java/com/iluwatar/leaderfollowers/Worker.java diff --git a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/AppTest.java b/leader-followers/src/test/java/com/AppTest.java similarity index 83% rename from leader-followers/src/test/java/com.iluwatar.leaderfollowers/AppTest.java rename to leader-followers/src/test/java/com/AppTest.java index 00fbfe4d2..3d0588fef 100644 --- a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/AppTest.java +++ b/leader-followers/src/test/java/com/AppTest.java @@ -21,10 +21,13 @@ * THE SOFTWARE. */ -package com.iluwatar.leaderfollowers; +package com; +import com.iluwatar.leaderfollowers.App; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * * Application test @@ -33,9 +36,8 @@ import org.junit.Test; public class AppTest { @Test - public void test() throws InterruptedException { - String[] args = {}; - App.main(args); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskHandlerTest.java b/leader-followers/src/test/java/com/TaskHandlerTest.java similarity index 93% rename from leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskHandlerTest.java rename to leader-followers/src/test/java/com/TaskHandlerTest.java index 9fb39c922..7dc44c04f 100644 --- a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskHandlerTest.java +++ b/leader-followers/src/test/java/com/TaskHandlerTest.java @@ -21,8 +21,10 @@ * THE SOFTWARE. */ -package com.iluwatar.leaderfollowers; +package com; +import com.iluwatar.leaderfollowers.Task; +import com.iluwatar.leaderfollowers.TaskHandler; import org.junit.Assert; import org.junit.Test; diff --git a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskSetTest.java b/leader-followers/src/test/java/com/TaskSetTest.java similarity index 94% rename from leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskSetTest.java rename to leader-followers/src/test/java/com/TaskSetTest.java index 53cb31deb..e3691d220 100644 --- a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/TaskSetTest.java +++ b/leader-followers/src/test/java/com/TaskSetTest.java @@ -21,8 +21,10 @@ * THE SOFTWARE. */ -package com.iluwatar.leaderfollowers; +package com; +import com.iluwatar.leaderfollowers.Task; +import com.iluwatar.leaderfollowers.TaskSet; import org.junit.Assert; import org.junit.Test; diff --git a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/WorkCenterTest.java b/leader-followers/src/test/java/com/WorkCenterTest.java similarity index 93% rename from leader-followers/src/test/java/com.iluwatar.leaderfollowers/WorkCenterTest.java rename to leader-followers/src/test/java/com/WorkCenterTest.java index 045d8c3dc..41e9ff43f 100644 --- a/leader-followers/src/test/java/com.iluwatar.leaderfollowers/WorkCenterTest.java +++ b/leader-followers/src/test/java/com/WorkCenterTest.java @@ -21,8 +21,11 @@ * THE SOFTWARE. */ -package com.iluwatar.leaderfollowers; +package com; +import com.iluwatar.leaderfollowers.TaskHandler; +import com.iluwatar.leaderfollowers.TaskSet; +import com.iluwatar.leaderfollowers.WorkCenter; import org.junit.Assert; import org.junit.Test; diff --git a/marker/src/test/java/AppTest.java b/marker/src/test/java/AppTest.java index 13295a9e5..17a13c167 100644 --- a/marker/src/test/java/AppTest.java +++ b/marker/src/test/java/AppTest.java @@ -23,13 +23,15 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/mediator/src/test/java/com/iluwatar/mediator/AppTest.java b/mediator/src/test/java/com/iluwatar/mediator/AppTest.java index 23f2a72f2..558ec4907 100644 --- a/mediator/src/test/java/com/iluwatar/mediator/AppTest.java +++ b/mediator/src/test/java/com/iluwatar/mediator/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.mediator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/memento/src/test/java/com/iluwatar/memento/AppTest.java b/memento/src/test/java/com/iluwatar/memento/AppTest.java index e0448c289..2d8a518e2 100644 --- a/memento/src/test/java/com/iluwatar/memento/AppTest.java +++ b/memento/src/test/java/com/iluwatar/memento/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.memento; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java index 69dc19f1c..a0fdbf3ba 100644 --- a/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java +++ b/model-view-controller/src/test/java/com/iluwatar/model/view/controller/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.model.view.controller; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 1d59b5d8c..1dd1bf818 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -35,6 +35,10 @@ import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; +import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; +import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; +import static javax.swing.WindowConstants.EXIT_ON_CLOSE; + /** * This class is the GUI implementation of the View component in the Model-View-Presenter pattern. */ @@ -80,7 +84,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti */ public FileSelectorJFrame() { super("File Loader"); - this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLayout(null); this.setBounds(100, 100, 500, 200); @@ -119,8 +123,8 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti */ this.area = new JTextArea(100, 100); var pane = new JScrollPane(area); - pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + pane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED); + pane.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED); panel.add(pane); this.area.setEditable(false); pane.setBounds(150, 100, 250, 80); diff --git a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java index 4db990a2d..6529cd18d 100644 --- a/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java +++ b/model-view-presenter/src/test/java/com/iluwatar/model/view/presenter/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.model.view.presenter; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/module/src/test/java/com/iluwatar/module/AppTest.java b/module/src/test/java/com/iluwatar/module/AppTest.java index 8dcfd565e..4bf72fcb0 100644 --- a/module/src/test/java/com/iluwatar/module/AppTest.java +++ b/module/src/test/java/com/iluwatar/module/AppTest.java @@ -25,14 +25,17 @@ package com.iluwatar.module; import java.io.FileNotFoundException; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; /** * Tests that Module example runs without errors. */ -public final class AppTest { +final class AppTest { @Test - public void test() throws FileNotFoundException { - App.main(); + void shouldExecuteWithoutException() { + assertDoesNotThrow((Executable) App::main); } } diff --git a/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java b/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java index 5883812c7..c5ce35582 100644 --- a/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java +++ b/mute-idiom/src/test/java/com/iluwatar/mute/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.mute; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Mute idiom example runs without errors. */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java b/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java index 33d104ffc..e92b26f9b 100644 --- a/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java +++ b/mute-idiom/src/test/java/com/iluwatar/mute/MuteTest.java @@ -23,41 +23,40 @@ package com.iluwatar.mute; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.junit.jupiter.api.Assertions.*; + /** * Test for the mute-idiom pattern */ -public class MuteTest { +class MuteTest { private static final Logger LOGGER = LoggerFactory.getLogger(MuteTest.class); private static final String MESSAGE = "should not occur"; @Test - public void muteShouldRunTheCheckedRunnableAndNotThrowAnyExceptionIfCheckedRunnableDoesNotThrowAnyException() { - Mute.mute(this::methodNotThrowingAnyException); + void muteShouldRunTheCheckedRunnableAndNotThrowAnyExceptionIfCheckedRunnableDoesNotThrowAnyException() { + assertDoesNotThrow(() -> Mute.mute(this::methodNotThrowingAnyException)); } @Test - public void muteShouldRethrowUnexpectedExceptionAsAssertionError() { + void muteShouldRethrowUnexpectedExceptionAsAssertionError() { assertThrows(AssertionError.class, () -> Mute.mute(this::methodThrowingException)); } @Test - public void loggedMuteShouldRunTheCheckedRunnableAndNotThrowAnyExceptionIfCheckedRunnableDoesNotThrowAnyException() { - Mute.loggedMute(this::methodNotThrowingAnyException); + void loggedMuteShouldRunTheCheckedRunnableAndNotThrowAnyExceptionIfCheckedRunnableDoesNotThrowAnyException() { + assertDoesNotThrow(() -> Mute.mute(this::methodNotThrowingAnyException)); } @Test - public void loggedMuteShouldLogExceptionTraceBeforeSwallowingIt() { + void loggedMuteShouldLogExceptionTraceBeforeSwallowingIt() { var stream = new ByteArrayOutputStream(); System.setErr(new PrintStream(stream)); diff --git a/mutex/src/test/java/com/iluwatar/mutex/AppTest.java b/mutex/src/test/java/com/iluwatar/mutex/AppTest.java index 0bee249a6..7866b22a8 100644 --- a/mutex/src/test/java/com/iluwatar/mutex/AppTest.java +++ b/mutex/src/test/java/com/iluwatar/mutex/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.mutex; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test Entrypoint */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java b/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java index 754aadc80..27724a724 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.nullobject; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java b/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java index aeec371ff..5862d1e1a 100644 --- a/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java +++ b/null-object/src/test/java/com/iluwatar/nullobject/NullNodeTest.java @@ -35,20 +35,20 @@ import static org.junit.jupiter.api.Assertions.assertSame; * * @author Jeroen Meulemeester */ -public class NullNodeTest { +class NullNodeTest { /** * Verify if {@link NullNode#getInstance()} actually returns the same object instance */ @Test - public void testGetInstance() { + void testGetInstance() { final var instance = NullNode.getInstance(); assertNotNull(instance); assertSame(instance, NullNode.getInstance()); } @Test - public void testFields() { + void testFields() { final var node = NullNode.getInstance(); assertEquals(0, node.getTreeSize()); assertNull(node.getName()); @@ -56,9 +56,8 @@ public class NullNodeTest { assertNull(node.getRight()); } - @Test - public void testWalk() { - NullNode.getInstance().walk(); - } + /** + * Removed unnecessary test method for {@link NullNode#walk()} as the method doesn't have an implementation. + */ } diff --git a/object-pool/src/main/java/com/iluwatar/object/pool/App.java b/object-pool/src/main/java/com/iluwatar/object/pool/App.java index cbfc7dea5..48957ce24 100644 --- a/object-pool/src/main/java/com/iluwatar/object/pool/App.java +++ b/object-pool/src/main/java/com/iluwatar/object/pool/App.java @@ -57,12 +57,14 @@ public class App { var pool = new OliphauntPool(); LOGGER.info(pool.toString()); var oliphaunt1 = pool.checkOut(); - LOGGER.info("Checked out {}", oliphaunt1); + String checkedOut = "Checked out {}"; + + LOGGER.info(checkedOut, oliphaunt1); LOGGER.info(pool.toString()); var oliphaunt2 = pool.checkOut(); - LOGGER.info("Checked out {}", oliphaunt2); + LOGGER.info(checkedOut, oliphaunt2); var oliphaunt3 = pool.checkOut(); - LOGGER.info("Checked out {}", oliphaunt3); + LOGGER.info(checkedOut, oliphaunt3); LOGGER.info(pool.toString()); LOGGER.info("Checking in {}", oliphaunt1); pool.checkIn(oliphaunt1); @@ -70,9 +72,9 @@ public class App { pool.checkIn(oliphaunt2); LOGGER.info(pool.toString()); var oliphaunt4 = pool.checkOut(); - LOGGER.info("Checked out {}", oliphaunt4); + LOGGER.info(checkedOut, oliphaunt4); var oliphaunt5 = pool.checkOut(); - LOGGER.info("Checked out {}", oliphaunt5); + LOGGER.info(checkedOut, oliphaunt5); LOGGER.info(pool.toString()); } } diff --git a/object-pool/src/test/java/com/iluwatar/object/pool/AppTest.java b/object-pool/src/test/java/com/iluwatar/object/pool/AppTest.java index 7113f9304..f36563a8c 100644 --- a/object-pool/src/test/java/com/iluwatar/object/pool/AppTest.java +++ b/object-pool/src/test/java/com/iluwatar/object/pool/AppTest.java @@ -30,11 +30,10 @@ import org.junit.jupiter.api.Test; * Application test * */ -public class AppTest { +class AppTest { @Test - public void test() { - String[] args = {}; - App.main(args); + void shouldExecuteApplicationWithoutException() { + App.main(new String[]{}); } } diff --git a/observer/src/test/java/com/iluwatar/observer/AppTest.java b/observer/src/test/java/com/iluwatar/observer/AppTest.java index b557fdf7e..6b1f426d6 100644 --- a/observer/src/test/java/com/iluwatar/observer/AppTest.java +++ b/observer/src/test/java/com/iluwatar/observer/AppTest.java @@ -25,16 +25,17 @@ package com.iluwatar.observer; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * * Application test * */ -public class AppTest { +class AppTest { @Test - public void test() { - String[] args = {}; - App.main(args); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/partial-response/pom.xml b/partial-response/pom.xml index 83d81bf82..eb094874f 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -44,6 +44,11 @@ junit-vintage-engine test + + org.junit.jupiter + junit-jupiter-engine + test + org.mockito mockito-core diff --git a/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java b/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java index d50084a36..b00ee6861 100644 --- a/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java +++ b/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.partialresponse; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ public class AppTest { @Test - public void main() throws Exception { - App.main(new String[]{}); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/pipeline/src/test/java/com/iluwatar/pipeline/AppTest.java b/pipeline/src/test/java/com/iluwatar/pipeline/AppTest.java index 8ea6a4c60..1316491ad 100644 --- a/pipeline/src/test/java/com/iluwatar/pipeline/AppTest.java +++ b/pipeline/src/test/java/com/iluwatar/pipeline/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.pipeline; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/poison-pill/src/test/java/com/iluwatar/poison/pill/AppTest.java b/poison-pill/src/test/java/com/iluwatar/poison/pill/AppTest.java index c23fe5563..50d7a90c9 100644 --- a/poison-pill/src/test/java/com/iluwatar/poison/pill/AppTest.java +++ b/poison-pill/src/test/java/com/iluwatar/poison/pill/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.poison.pill; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/private-class-data/src/test/java/com/iluwatar/privateclassdata/AppTest.java b/private-class-data/src/test/java/com/iluwatar/privateclassdata/AppTest.java index 166ddbdee..d551614cf 100644 --- a/private-class-data/src/test/java/com/iluwatar/privateclassdata/AppTest.java +++ b/private-class-data/src/test/java/com/iluwatar/privateclassdata/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.privateclassdata; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/producer-consumer/src/test/java/com/iluwatar/producer/consumer/AppTest.java b/producer-consumer/src/test/java/com/iluwatar/producer/consumer/AppTest.java index bf4b6cc66..0a436bd02 100644 --- a/producer-consumer/src/test/java/com/iluwatar/producer/consumer/AppTest.java +++ b/producer-consumer/src/test/java/com/iluwatar/producer/consumer/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.producer.consumer; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/promise/src/main/java/com/iluwatar/promise/Promise.java b/promise/src/main/java/com/iluwatar/promise/Promise.java index 9eecf00eb..e81cccb58 100644 --- a/promise/src/main/java/com/iluwatar/promise/Promise.java +++ b/promise/src/main/java/com/iluwatar/promise/Promise.java @@ -47,6 +47,7 @@ public class Promise extends PromiseSupport { * Creates a promise that will be fulfilled in future. */ public Promise() { + // Empty constructor } /** diff --git a/promise/src/test/java/com/iluwatar/promise/AppTest.java b/promise/src/test/java/com/iluwatar/promise/AppTest.java index 63ac06aec..bf2f264c0 100644 --- a/promise/src/test/java/com/iluwatar/promise/AppTest.java +++ b/promise/src/test/java/com/iluwatar/promise/AppTest.java @@ -26,13 +26,15 @@ package com.iluwatar.promise; import java.util.concurrent.ExecutionException; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test. */ -public class AppTest { +class AppTest { @Test - public void testApp() throws InterruptedException, ExecutionException { - App.main(null); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(null)); } } diff --git a/promise/src/test/java/com/iluwatar/promise/PromiseTest.java b/promise/src/test/java/com/iluwatar/promise/PromiseTest.java index a72faf01e..3b6d43be2 100644 --- a/promise/src/test/java/com/iluwatar/promise/PromiseTest.java +++ b/promise/src/test/java/com/iluwatar/promise/PromiseTest.java @@ -67,7 +67,7 @@ public class PromiseTest { @Test public void promiseIsFulfilledWithAnExceptionIfTaskThrowsAnException() - throws InterruptedException, TimeoutException { + throws InterruptedException { testWaitingForeverForPromiseToBeFulfilled(); testWaitingSomeTimeForPromiseToBeFulfilled(); } diff --git a/property/src/main/java/com/iluwatar/property/Character.java b/property/src/main/java/com/iluwatar/property/Character.java index afe9fe16c..3d3813e5f 100644 --- a/property/src/main/java/com/iluwatar/property/Character.java +++ b/property/src/main/java/com/iluwatar/property/Character.java @@ -61,10 +61,12 @@ public class Character implements Prototype { @Override public void set(Stats stat, Integer val) { + // Does Nothing } @Override public void remove(Stats stat) { + // Does Nothing. } }; } diff --git a/property/src/test/java/com/iluwatar/property/AppTest.java b/property/src/test/java/com/iluwatar/property/AppTest.java index 89c0dcbf6..38c5cb4d5 100644 --- a/property/src/test/java/com/iluwatar/property/AppTest.java +++ b/property/src/test/java/com/iluwatar/property/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.property; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/prototype/src/test/java/com/iluwatar/prototype/AppTest.java b/prototype/src/test/java/com/iluwatar/prototype/AppTest.java index 489b6365c..d82568ddf 100644 --- a/prototype/src/test/java/com/iluwatar/prototype/AppTest.java +++ b/prototype/src/test/java/com/iluwatar/prototype/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.prototype; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/proxy/src/test/java/com/iluwatar/proxy/AppTest.java b/proxy/src/test/java/com/iluwatar/proxy/AppTest.java index 2fdd5253e..dde0bbe57 100644 --- a/proxy/src/test/java/com/iluwatar/proxy/AppTest.java +++ b/proxy/src/test/java/com/iluwatar/proxy/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.proxy; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/AppTest.java b/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/AppTest.java index 55c9528e6..2adc15011 100644 --- a/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/AppTest.java +++ b/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.queue.load.leveling; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java b/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java index 1e81c5d11..3d12e6abf 100644 --- a/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java +++ b/queue-load-leveling/src/test/java/com/iluwatar/queue/load/leveling/TaskGenSrvExeTest.java @@ -25,14 +25,17 @@ package com.iluwatar.queue.load.leveling; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * Test case for submitting Message to Blocking Queue by TaskGenerator and retrieve the message by * ServiceExecutor. */ -public class TaskGenSrvExeTest { +class TaskGenSrvExeTest { @Test - public void taskGeneratorTest() { + void taskGeneratorTest() { var msgQueue = new MessageQueue(); // Create a task generator thread with 1 job to submit. @@ -40,10 +43,14 @@ public class TaskGenSrvExeTest { var taskGenThr = new Thread(taskRunnable); taskGenThr.start(); + assertNotNull(taskGenThr); + // Create a service executor thread. var srvRunnable = new ServiceExecutor(msgQueue); var srvExeThr = new Thread(srvRunnable); srvExeThr.start(); + + assertNotNull(srvExeThr); } } diff --git a/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java b/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java index 76ddfbdba..1d7faab7e 100644 --- a/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java +++ b/reactor/src/test/java/com/iluwatar/reactor/app/ReactorTest.java @@ -30,6 +30,9 @@ import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + /** * This class tests the Distributed Logging service by starting a Reactor and then sending it * concurrent logging requests using multiple clients. @@ -50,9 +53,13 @@ public class ReactorTest { var app = new App(new ThreadPoolDispatcher(2)); app.start(); + assertNotNull(app); + var client = new AppClient(); client.start(); + assertNotNull(client); + // allow clients to send requests. Artificial delay. try { Thread.sleep(2000); @@ -78,9 +85,13 @@ public class ReactorTest { var app = new App(new SameThreadDispatcher()); app.start(); + assertNotNull(app); + var client = new AppClient(); client.start(); + assertNotNull(client); + // allow clients to send requests. Artificial delay. try { Thread.sleep(2000); diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java index a0175e259..63f4c764d 100644 --- a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.reader.writer.lock; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/repository/src/test/java/com/iluwatar/repository/AppTest.java b/repository/src/test/java/com/iluwatar/repository/AppTest.java index b12f03d8c..d44af23db 100644 --- a/repository/src/test/java/com/iluwatar/repository/AppTest.java +++ b/repository/src/test/java/com/iluwatar/repository/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.repository; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Repository example runs without errors. */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/AppTest.java b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/AppTest.java index dedeee7e0..057a85500 100644 --- a/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/AppTest.java +++ b/resource-acquisition-is-initialization/src/test/java/com/iluwatar/resource/acquisition/is/initialization/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.resource.acquisition.is.initialization; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/retry/src/main/java/com/iluwatar/retry/App.java b/retry/src/main/java/com/iluwatar/retry/App.java index 06f43c29f..7d6e6faec 100644 --- a/retry/src/main/java/com/iluwatar/retry/App.java +++ b/retry/src/main/java/com/iluwatar/retry/App.java @@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory; */ public final class App { private static final Logger LOG = LoggerFactory.getLogger(App.class); + public static final String NOT_FOUND = "not found"; private static BusinessOperation op; /** @@ -81,7 +82,7 @@ public final class App { } private static void errorNoRetry() throws Exception { - op = new FindCustomer("123", new CustomerNotFoundException("not found")); + op = new FindCustomer("123", new CustomerNotFoundException(NOT_FOUND)); try { op.perform(); } catch (CustomerNotFoundException e) { @@ -91,7 +92,7 @@ public final class App { private static void errorWithRetry() throws Exception { final var retry = new Retry<>( - new FindCustomer("123", new CustomerNotFoundException("not found")), + new FindCustomer("123", new CustomerNotFoundException(NOT_FOUND)), 3, //3 attempts 100, //100 ms delay between attempts e -> CustomerNotFoundException.class.isAssignableFrom(e.getClass()) @@ -106,7 +107,7 @@ public final class App { private static void errorWithRetryExponentialBackoff() throws Exception { final var retry = new RetryExponentialBackoff<>( - new FindCustomer("123", new CustomerNotFoundException("not found")), + new FindCustomer("123", new CustomerNotFoundException(NOT_FOUND)), 6, //6 attempts 30000, //30 s max delay between attempts e -> CustomerNotFoundException.class.isAssignableFrom(e.getClass()) diff --git a/role-object/pom.xml b/role-object/pom.xml index ccb8219eb..c980adc2c 100644 --- a/role-object/pom.xml +++ b/role-object/pom.xml @@ -39,6 +39,11 @@ junit test + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/role-object/src/test/java/com/iluwatar/roleobject/ApplicationRoleObjectTest.java b/role-object/src/test/java/com/iluwatar/roleobject/ApplicationRoleObjectTest.java index eb8d57f4f..01535f477 100644 --- a/role-object/src/test/java/com/iluwatar/roleobject/ApplicationRoleObjectTest.java +++ b/role-object/src/test/java/com/iluwatar/roleobject/ApplicationRoleObjectTest.java @@ -24,10 +24,12 @@ package com.iluwatar.roleobject; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class ApplicationRoleObjectTest { @Test - public void mainTest() { - ApplicationRoleObject.main(new String[]{}); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> ApplicationRoleObject.main(new String[]{})); } } \ No newline at end of file diff --git a/saga/pom.xml b/saga/pom.xml index 08a5cdc77..1971ae6cf 100644 --- a/saga/pom.xml +++ b/saga/pom.xml @@ -40,6 +40,11 @@ junit test + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/saga/src/test/java/com/iluwatar/saga/choreography/SagaApplicationTest.java b/saga/src/test/java/com/iluwatar/saga/choreography/SagaApplicationTest.java index d7a2a34b2..5d73a9fa3 100644 --- a/saga/src/test/java/com/iluwatar/saga/choreography/SagaApplicationTest.java +++ b/saga/src/test/java/com/iluwatar/saga/choreography/SagaApplicationTest.java @@ -25,13 +25,15 @@ package com.iluwatar.saga.choreography; import com.iluwatar.saga.orchestration.SagaApplication; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /*** * empty test */ public class SagaApplicationTest { @Test - public void mainTest() { - SagaApplication.main(new String[]{}); + public void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> SagaApplication.main(new String[]{})); } } \ No newline at end of file diff --git a/semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java b/semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java index f450c0593..302796238 100644 --- a/semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java +++ b/semaphore/src/test/java/com/iluwatar/semaphore/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.semaphore; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application Test Entrypoint */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/servant/src/test/java/com/iluwatar/servant/AppTest.java b/servant/src/test/java/com/iluwatar/servant/AppTest.java index ab1e99e55..d05c22eeb 100644 --- a/servant/src/test/java/com/iluwatar/servant/AppTest.java +++ b/servant/src/test/java/com/iluwatar/servant/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.servant; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java b/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java index ea660f01e..e360e5c94 100644 --- a/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java +++ b/service-layer/src/main/java/com/iluwatar/servicelayer/app/App.java @@ -55,6 +55,7 @@ import org.slf4j.LoggerFactory; public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + public static final String BOOK_OF_IDORES = "Book of Idores"; /** * Program entry point. @@ -135,7 +136,7 @@ public class App { spellbook4.addSpell(spell11); spellbook4.addSpell(spell12); spellbookDao.merge(spellbook4); - var spellbook5 = new Spellbook("Book of Idores"); + var spellbook5 = new Spellbook(BOOK_OF_IDORES); spellbookDao.persist(spellbook5); spellbook5.addSpell(spell13); spellbookDao.merge(spellbook5); @@ -164,7 +165,7 @@ public class App { wizardDao.merge(wizard2); var wizard3 = new Wizard("Xuban Munoa"); wizardDao.persist(wizard3); - wizard3.addSpellbook(spellbookDao.findByName("Book of Idores")); + wizard3.addSpellbook(spellbookDao.findByName(BOOK_OF_IDORES)); wizard3.addSpellbook(spellbookDao.findByName("Book of Opaen")); wizardDao.merge(wizard3); var wizard4 = new Wizard("Blasius Dehooge"); @@ -188,7 +189,7 @@ public class App { LOGGER.info("Enumerating all spells"); service.findAllSpells().stream().map(Spell::getName).forEach(LOGGER::info); LOGGER.info("Find wizards with spellbook 'Book of Idores'"); - var wizardsWithSpellbook = service.findWizardsWithSpellbook("Book of Idores"); + var wizardsWithSpellbook = service.findWizardsWithSpellbook(BOOK_OF_IDORES); wizardsWithSpellbook.forEach(w -> LOGGER.info("{} has 'Book of Idores'", w.getName())); LOGGER.info("Find wizards with spell 'Fireball'"); var wizardsWithSpell = service.findWizardsWithSpell("Fireball"); diff --git a/service-layer/src/test/java/com/iluwatar/servicelayer/app/AppTest.java b/service-layer/src/test/java/com/iluwatar/servicelayer/app/AppTest.java index 26aa2b168..5cc1ccfff 100644 --- a/service-layer/src/test/java/com/iluwatar/servicelayer/app/AppTest.java +++ b/service-layer/src/test/java/com/iluwatar/servicelayer/app/AppTest.java @@ -27,18 +27,20 @@ import com.iluwatar.servicelayer.hibernate.HibernateUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } @AfterEach - public void tearDown() { + void tearDown() { HibernateUtil.dropSession(); } diff --git a/service-locator/src/main/java/com/iluwatar/servicelocator/App.java b/service-locator/src/main/java/com/iluwatar/servicelocator/App.java index efc25bd89..85419b603 100644 --- a/service-locator/src/main/java/com/iluwatar/servicelocator/App.java +++ b/service-locator/src/main/java/com/iluwatar/servicelocator/App.java @@ -37,19 +37,22 @@ package com.iluwatar.servicelocator; */ public class App { + public static final String JNDI_SERVICE_A = "jndi/serviceA"; + public static final String JNDI_SERVICE_B = "jndi/serviceB"; + /** * Program entry point. * * @param args command line args */ public static void main(String[] args) { - var service = ServiceLocator.getService("jndi/serviceA"); + var service = ServiceLocator.getService(JNDI_SERVICE_A); service.execute(); - service = ServiceLocator.getService("jndi/serviceB"); + service = ServiceLocator.getService(JNDI_SERVICE_B); service.execute(); - service = ServiceLocator.getService("jndi/serviceA"); + service = ServiceLocator.getService(JNDI_SERVICE_A); service.execute(); - service = ServiceLocator.getService("jndi/serviceA"); + service = ServiceLocator.getService(JNDI_SERVICE_A); service.execute(); } } diff --git a/service-locator/src/test/java/com/iluwatar/servicelocator/AppTest.java b/service-locator/src/test/java/com/iluwatar/servicelocator/AppTest.java index cb4c98c07..75d6f8b05 100644 --- a/service-locator/src/test/java/com/iluwatar/servicelocator/AppTest.java +++ b/service-locator/src/test/java/com/iluwatar/servicelocator/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.servicelocator; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/sharding/pom.xml b/sharding/pom.xml index a641ce375..2d00629bc 100644 --- a/sharding/pom.xml +++ b/sharding/pom.xml @@ -40,6 +40,11 @@ junit junit + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/sharding/src/main/java/com/iluwatar/sharding/App.java b/sharding/src/main/java/com/iluwatar/sharding/App.java index fe3cb7923..109f88cf8 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/App.java +++ b/sharding/src/main/java/com/iluwatar/sharding/App.java @@ -36,10 +36,10 @@ public class App { */ public static void main(String[] args) { - var data1 = new Data(1, "data1", Data.DataType.type1); - var data2 = new Data(2, "data2", Data.DataType.type2); - var data3 = new Data(3, "data3", Data.DataType.type3); - var data4 = new Data(4, "data4", Data.DataType.type1); + var data1 = new Data(1, "data1", Data.DataType.TYPE_1); + var data2 = new Data(2, "data2", Data.DataType.TYPE_2); + var data3 = new Data(3, "data3", Data.DataType.TYPE_3); + var data4 = new Data(4, "data4", Data.DataType.TYPE_1); var shard1 = new Shard(1); var shard2 = new Shard(2); diff --git a/sharding/src/main/java/com/iluwatar/sharding/Data.java b/sharding/src/main/java/com/iluwatar/sharding/Data.java index 92e84e93a..abe49f15d 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/Data.java +++ b/sharding/src/main/java/com/iluwatar/sharding/Data.java @@ -71,7 +71,7 @@ public class Data { } enum DataType { - type1, type2, type3 + TYPE_1, TYPE_2, TYPE_3 } @Override diff --git a/sharding/src/main/java/com/iluwatar/sharding/RangeShardManager.java b/sharding/src/main/java/com/iluwatar/sharding/RangeShardManager.java index bdb862571..d06cd51da 100644 --- a/sharding/src/main/java/com/iluwatar/sharding/RangeShardManager.java +++ b/sharding/src/main/java/com/iluwatar/sharding/RangeShardManager.java @@ -47,11 +47,11 @@ public class RangeShardManager extends ShardManager { protected int allocateShard(Data data) { var type = data.getType(); switch (type) { - case type1: + case TYPE_1: return 1; - case type2: + case TYPE_2: return 2; - case type3: + case TYPE_3: return 3; default: return -1; diff --git a/sharding/src/test/java/com/iluwatar/sharding/AppTest.java b/sharding/src/test/java/com/iluwatar/sharding/AppTest.java index 40e6391bf..f23b71d1e 100644 --- a/sharding/src/test/java/com/iluwatar/sharding/AppTest.java +++ b/sharding/src/test/java/com/iluwatar/sharding/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.sharding; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Unit tests for App class. */ public class AppTest { @Test - public void testMain() { - App.main(new String[]{}); + public void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/sharding/src/test/java/com/iluwatar/sharding/HashShardManagerTest.java b/sharding/src/test/java/com/iluwatar/sharding/HashShardManagerTest.java index 6418cf0c4..e19de75d2 100644 --- a/sharding/src/test/java/com/iluwatar/sharding/HashShardManagerTest.java +++ b/sharding/src/test/java/com/iluwatar/sharding/HashShardManagerTest.java @@ -56,7 +56,7 @@ public class HashShardManagerTest { @Test public void testStoreData() { - var data = new Data(1, "test", Data.DataType.type1); + var data = new Data(1, "test", Data.DataType.TYPE_1); hashShardManager.storeData(data); Assert.assertEquals(data, hashShardManager.getShardById(1).getDataById(1)); } diff --git a/sharding/src/test/java/com/iluwatar/sharding/LookupShardManagerTest.java b/sharding/src/test/java/com/iluwatar/sharding/LookupShardManagerTest.java index 70650bb50..c6ce5851d 100644 --- a/sharding/src/test/java/com/iluwatar/sharding/LookupShardManagerTest.java +++ b/sharding/src/test/java/com/iluwatar/sharding/LookupShardManagerTest.java @@ -52,7 +52,7 @@ public class LookupShardManagerTest { @Test public void testStoreData() { try { - var data = new Data(1, "test", Data.DataType.type1); + var data = new Data(1, "test", Data.DataType.TYPE_1); lookupShardManager.storeData(data); var field = LookupShardManager.class.getDeclaredField("lookupMap"); field.setAccessible(true); diff --git a/sharding/src/test/java/com/iluwatar/sharding/RangeShardManagerTest.java b/sharding/src/test/java/com/iluwatar/sharding/RangeShardManagerTest.java index 997687dfc..9ea4a2d86 100644 --- a/sharding/src/test/java/com/iluwatar/sharding/RangeShardManagerTest.java +++ b/sharding/src/test/java/com/iluwatar/sharding/RangeShardManagerTest.java @@ -50,7 +50,7 @@ public class RangeShardManagerTest { @Test public void testStoreData() { - var data = new Data(1, "test", Data.DataType.type1); + var data = new Data(1, "test", Data.DataType.TYPE_1); rangeShardManager.storeData(data); Assert.assertEquals(data, rangeShardManager.getShardById(1).getDataById(1)); } diff --git a/sharding/src/test/java/com/iluwatar/sharding/ShardTest.java b/sharding/src/test/java/com/iluwatar/sharding/ShardTest.java index a747933af..a12ab3a97 100644 --- a/sharding/src/test/java/com/iluwatar/sharding/ShardTest.java +++ b/sharding/src/test/java/com/iluwatar/sharding/ShardTest.java @@ -42,7 +42,7 @@ public class ShardTest { @Before public void setup() { - data = new Data(1, "test", Data.DataType.type1); + data = new Data(1, "test", Data.DataType.TYPE_1); shard = new Shard(1); } diff --git a/singleton/src/test/java/com/iluwatar/singleton/AppTest.java b/singleton/src/test/java/com/iluwatar/singleton/AppTest.java index b7c55ddea..5d3f247de 100644 --- a/singleton/src/test/java/com/iluwatar/singleton/AppTest.java +++ b/singleton/src/test/java/com/iluwatar/singleton/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.singleton; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test. */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/spatial-partition/src/main/java/com/iluwatar/spatialpartition/App.java b/spatial-partition/src/main/java/com/iluwatar/spatialpartition/App.java index 8a0e2383c..083d6a019 100644 --- a/spatial-partition/src/main/java/com/iluwatar/spatialpartition/App.java +++ b/spatial-partition/src/main/java/com/iluwatar/spatialpartition/App.java @@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory; public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + private static final String BUBBLE = "Bubble "; static void noSpatialPartition(int numOfMovements, Hashtable bubbles) { //all bubbles have to be checked for collision for all bubbles @@ -76,7 +77,7 @@ public class App { numOfMovements--; } //bubbles not popped - bubbles.keySet().stream().map(key -> "Bubble " + key + " not popped").forEach(LOGGER::info); + bubbles.keySet().stream().map(key -> BUBBLE + key + " not popped").forEach(LOGGER::info); } static void withSpatialPartition( @@ -99,7 +100,7 @@ public class App { numOfMovements--; } //bubbles not popped - bubbles.keySet().stream().map(key -> "Bubble " + key + " not popped").forEach(LOGGER::info); + bubbles.keySet().stream().map(key -> BUBBLE + key + " not popped").forEach(LOGGER::info); } /** @@ -116,7 +117,7 @@ public class App { var b = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1); bubbles1.put(i, b); bubbles2.put(i, b); - LOGGER.info("Bubble " + i + " with radius " + b.radius + LOGGER.info(BUBBLE + i + " with radius " + b.radius + " added at (" + b.coordinateX + "," + b.coordinateY + ")"); } diff --git a/spatial-partition/src/main/java/com/iluwatar/spatialpartition/SpatialPartitionBubbles.java b/spatial-partition/src/main/java/com/iluwatar/spatialpartition/SpatialPartitionBubbles.java index b3f60632f..c0eb5ecde 100644 --- a/spatial-partition/src/main/java/com/iluwatar/spatialpartition/SpatialPartitionBubbles.java +++ b/spatial-partition/src/main/java/com/iluwatar/spatialpartition/SpatialPartitionBubbles.java @@ -34,8 +34,8 @@ import java.util.Hashtable; public class SpatialPartitionBubbles extends SpatialPartitionGeneric { - final Hashtable bubbles; - final QuadTree quadTree; + private final Hashtable bubbles; + private final QuadTree quadTree; SpatialPartitionBubbles(Hashtable bubbles, QuadTree quadTree) { this.bubbles = bubbles; diff --git a/specification/src/test/java/com/iluwatar/specification/app/AppTest.java b/specification/src/test/java/com/iluwatar/specification/app/AppTest.java index bc6f2226f..4b29e11e8 100644 --- a/specification/src/test/java/com/iluwatar/specification/app/AppTest.java +++ b/specification/src/test/java/com/iluwatar/specification/app/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.specification.app; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/state/src/test/java/com/iluwatar/state/AppTest.java b/state/src/test/java/com/iluwatar/state/AppTest.java index 9f7b65ff2..90beddb33 100644 --- a/state/src/test/java/com/iluwatar/state/AppTest.java +++ b/state/src/test/java/com/iluwatar/state/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.state; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/step-builder/src/test/java/com/iluwatar/stepbuilder/AppTest.java b/step-builder/src/test/java/com/iluwatar/stepbuilder/AppTest.java index 1f3fc6238..20119b41b 100644 --- a/step-builder/src/test/java/com/iluwatar/stepbuilder/AppTest.java +++ b/step-builder/src/test/java/com/iluwatar/stepbuilder/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.stepbuilder; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/strangler/src/main/java/com/iluwatar/strangler/NewSource.java b/strangler/src/main/java/com/iluwatar/strangler/NewSource.java index f53a31bd8..8cc1822fe 100644 --- a/strangler/src/main/java/com/iluwatar/strangler/NewSource.java +++ b/strangler/src/main/java/com/iluwatar/strangler/NewSource.java @@ -34,9 +34,10 @@ import org.slf4j.LoggerFactory; public class NewSource { private static final Logger LOGGER = LoggerFactory.getLogger(NewSource.class); private static final String VERSION = "2.0"; + public static final String SOURCE_MODULE = "Source module {}"; public int accumulateSum(int... nums) { - LOGGER.info("Source module {}", VERSION); + LOGGER.info(SOURCE_MODULE, VERSION); return Arrays.stream(nums).reduce(0, Integer::sum); } @@ -45,12 +46,12 @@ public class NewSource { * Replace old one in {@link OldSource} */ public int accumulateMul(int... nums) { - LOGGER.info("Source module {}", VERSION); + LOGGER.info(SOURCE_MODULE, VERSION); return Arrays.stream(nums).reduce(1, (a, b) -> a * b); } public boolean ifNonZero(int... nums) { - LOGGER.info("Source module {}", VERSION); + LOGGER.info(SOURCE_MODULE, VERSION); return Arrays.stream(nums).allMatch(num -> num != 0); } } diff --git a/strangler/src/test/java/com/iluwatar/strangler/AppTest.java b/strangler/src/test/java/com/iluwatar/strangler/AppTest.java index a9e878a94..7e45d63ec 100644 --- a/strangler/src/test/java/com/iluwatar/strangler/AppTest.java +++ b/strangler/src/test/java/com/iluwatar/strangler/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.strangler; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { + @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/strategy/src/test/java/com/iluwatar/strategy/AppTest.java b/strategy/src/test/java/com/iluwatar/strategy/AppTest.java index f1137c4c5..174334f51 100644 --- a/strategy/src/test/java/com/iluwatar/strategy/AppTest.java +++ b/strategy/src/test/java/com/iluwatar/strategy/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.strategy; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test. */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/subclass-sandbox/pom.xml b/subclass-sandbox/pom.xml index 264343b00..ac718291e 100644 --- a/subclass-sandbox/pom.xml +++ b/subclass-sandbox/pom.xml @@ -44,6 +44,11 @@ com.github.stefanbirkner system-rules + + org.junit.jupiter + junit-jupiter-engine + test + \ No newline at end of file diff --git a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/AppTest.java b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/AppTest.java index 83ba5315f..8d4865f6b 100644 --- a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/AppTest.java +++ b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.subclasssandbox; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * App unit tests. */ public class AppTest { @Test - public void testMain() { - App.main(new String[]{}); + public void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/template-method/src/test/java/com/iluwatar/templatemethod/AppTest.java b/template-method/src/test/java/com/iluwatar/templatemethod/AppTest.java index e70e8a78f..32f09242e 100644 --- a/template-method/src/test/java/com/iluwatar/templatemethod/AppTest.java +++ b/template-method/src/test/java/com/iluwatar/templatemethod/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.templatemethod; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/thread-pool/src/test/java/com/iluwatar/threadpool/AppTest.java b/thread-pool/src/test/java/com/iluwatar/threadpool/AppTest.java index ca6dc30e4..4c1cf90d6 100644 --- a/thread-pool/src/test/java/com/iluwatar/threadpool/AppTest.java +++ b/thread-pool/src/test/java/com/iluwatar/threadpool/AppTest.java @@ -25,15 +25,17 @@ package com.iluwatar.threadpool; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test * * @author ilkka */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/throttling/src/test/java/com/iluwatar/throttling/AppTest.java b/throttling/src/test/java/com/iluwatar/throttling/AppTest.java index daf8c2f21..dcabb02b3 100644 --- a/throttling/src/test/java/com/iluwatar/throttling/AppTest.java +++ b/throttling/src/test/java/com/iluwatar/throttling/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.throttling; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/tls/src/test/java/com/iluwatar/tls/AppTest.java b/tls/src/test/java/com/iluwatar/tls/AppTest.java index bae673b97..ba3774b3e 100644 --- a/tls/src/test/java/com/iluwatar/tls/AppTest.java +++ b/tls/src/test/java/com/iluwatar/tls/AppTest.java @@ -25,14 +25,16 @@ package com.iluwatar.tls; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that thread local storage example runs without errors. * * @author Thomas Bauer, January 2017 */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } 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 f6a9e6a0e..98ad31fe5 100644 --- a/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java +++ b/tolerant-reader/src/main/java/com/iluwatar/tolerantreader/RainbowFishSerializer.java @@ -38,6 +38,9 @@ import java.util.Map; */ public final class RainbowFishSerializer { + public static final String LENGTH_METERS = "lengthMeters"; + public static final String WEIGHT_TONS = "weightTons"; + private RainbowFishSerializer() { } @@ -48,8 +51,8 @@ public final class RainbowFishSerializer { 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()) + LENGTH_METERS, String.format("%d", rainbowFish.getLengthMeters()), + WEIGHT_TONS, String.format("%d", rainbowFish.getWeightTons()) ); try (var fileOut = new FileOutputStream(filename); @@ -65,8 +68,8 @@ public final class RainbowFishSerializer { 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()), + "lengthMeters", String.format("%d", rainbowFish.getLengthMeters()), + WEIGHT_TONS, String.format("%d", rainbowFish.getWeightTons()), "angry", Boolean.toString(rainbowFish.getAngry()), "hungry", Boolean.toString(rainbowFish.getHungry()), "sleeping", Boolean.toString(rainbowFish.getSleeping()) @@ -93,7 +96,7 @@ public final class RainbowFishSerializer { map.get("name"), Integer.parseInt(map.get("age")), Integer.parseInt(map.get("lengthMeters")), - Integer.parseInt(map.get("weightTons")) + Integer.parseInt(map.get(WEIGHT_TONS)) ); } } diff --git a/tolerant-reader/src/test/java/com/iluwatar/tolerantreader/AppTest.java b/tolerant-reader/src/test/java/com/iluwatar/tolerantreader/AppTest.java index d28e118d2..4b9432408 100644 --- a/tolerant-reader/src/test/java/com/iluwatar/tolerantreader/AppTest.java +++ b/tolerant-reader/src/test/java/com/iluwatar/tolerantreader/AppTest.java @@ -29,19 +29,21 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() throws ClassNotFoundException, IOException { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } @BeforeEach @AfterEach - public void cleanup() { + void cleanup() { var file1 = new File("fish1.out"); file1.delete(); var file2 = new File("fish2.out"); diff --git a/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java b/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java index 425d6e153..eb819cabe 100644 --- a/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java +++ b/transaction-script/src/test/java/com/iluwatar/transactionscript/AppTest.java @@ -25,12 +25,15 @@ package com.iluwatar.transactionscript; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Tests that Transaction script example runs without errors. */ -public class AppTest { +class AppTest { + @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/twin/src/test/java/com/iluwatar/twin/AppTest.java b/twin/src/test/java/com/iluwatar/twin/AppTest.java index 50b787eeb..38a3208ad 100644 --- a/twin/src/test/java/com/iluwatar/twin/AppTest.java +++ b/twin/src/test/java/com/iluwatar/twin/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.twin; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() throws Exception { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java index 88bfe0ada..7183c99df 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java @@ -30,8 +30,8 @@ package com.iluwatar.typeobject; public class Candy { enum Type { - crushableCandy, - rewardFruit + CRUSHABLE_CANDY, + REWARD_FRUIT } String name; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java index 04e281a99..ab175e660 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java @@ -104,13 +104,13 @@ public class CandyGame { boolean continueRound() { for (var i = 0; i < this.cells.length; i++) { - if (this.cells[cells.length - 1][i].candy.getType().equals(Type.rewardFruit)) { + if (this.cells[cells.length - 1][i].candy.getType().equals(Type.REWARD_FRUIT)) { return true; } } for (var i = 0; i < this.cells.length; i++) { for (var j = 0; j < this.cells.length; j++) { - if (!this.cells[i][j].candy.getType().equals(Type.rewardFruit)) { + if (!this.cells[i][j].candy.getType().equals(Type.REWARD_FRUIT)) { var adj = adjacentCells(i, j); for (Cell cell : adj) { if (this.cells[i][j].candy.name.equals(cell.candy.name)) { @@ -136,7 +136,7 @@ public class CandyGame { for (var i = 0; i < this.cells.length; i++) { var points = 0; var j = this.cells.length - 1; - while (this.cells[j][i].candy.getType().equals(Type.rewardFruit)) { + while (this.cells[j][i].candy.getType().equals(Type.REWARD_FRUIT)) { points = this.cells[j][i].candy.getPoints(); this.cells[j][i].crush(pool, this.cells); handleChange(points); diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java index e4d9d497f..76629b9dd 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java @@ -74,8 +74,8 @@ public class Cell { } int interact(Cell c, CellPool pool, Cell[][] cellMatrix) { - if (this.candy.getType().equals(Type.rewardFruit) || c.candy.getType() - .equals(Type.rewardFruit)) { + if (this.candy.getType().equals(Type.REWARD_FRUIT) || c.candy.getType() + .equals(Type.REWARD_FRUIT)) { return 0; } else { if (this.candy.name.equals(c.candy.name)) { diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java index f33640f2a..923a5c403 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java @@ -24,7 +24,7 @@ package com.iluwatar.typeobject; import com.iluwatar.typeobject.Candy.Type; -import java.io.FileNotFoundException; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -39,6 +39,8 @@ import org.json.simple.parser.ParseException; public class CellPool { private static final Random RANDOM = new Random(); + public static final String FRUIT = "fruit"; + public static final String CANDY = "candy"; List pool; int pointer; Candy[] randomCode; @@ -51,11 +53,11 @@ public class CellPool { e.printStackTrace(); //manually initialising this.randomCode this.randomCode = new Candy[5]; - randomCode[0] = new Candy("cherry", "fruit", Type.rewardFruit, 20); - randomCode[1] = new Candy("mango", "fruit", Type.rewardFruit, 20); - randomCode[2] = new Candy("purple popsicle", "candy", Type.crushableCandy, 10); - randomCode[3] = new Candy("green jellybean", "candy", Type.crushableCandy, 10); - randomCode[4] = new Candy("orange gum", "candy", Type.crushableCandy, 10); + randomCode[0] = new Candy("cherry", FRUIT, Type.REWARD_FRUIT, 20); + randomCode[1] = new Candy("mango", FRUIT, Type.REWARD_FRUIT, 20); + randomCode[2] = new Candy("purple popsicle", CANDY, Type.CRUSHABLE_CANDY, 10); + randomCode[3] = new Candy("green jellybean", CANDY, Type.CRUSHABLE_CANDY, 10); + randomCode[4] = new Candy("orange gum", CANDY, Type.CRUSHABLE_CANDY, 10); } for (int i = 0; i < num; i++) { var c = new Cell(); @@ -84,7 +86,7 @@ public class CellPool { var i = 0; for (var e = jp.candies.keys(); e.hasMoreElements(); ) { var s = e.nextElement(); - if (!s.equals("fruit") && !s.equals("candy")) { + if (!s.equals(FRUIT) && !s.equals(CANDY)) { //not generic randomCode[i] = jp.candies.get(s); i++; diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java index 01e709c8f..150c648d3 100644 --- a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java @@ -29,7 +29,7 @@ import java.io.FileReader; import java.io.IOException; import java.util.Hashtable; import java.util.List; -import java.util.stream.Collectors; + import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -58,9 +58,9 @@ public class JsonParser { var name = (String) candy.get("name"); var parentName = (String) candy.get("parent"); var t = (String) candy.get("type"); - var type = Type.crushableCandy; + var type = Type.CRUSHABLE_CANDY; if (t.equals("rewardFruit")) { - type = Type.rewardFruit; + type = Type.REWARD_FRUIT; } var points = Integer.parseInt((String) candy.get("points")); var c = new Candy(name, parentName, type, points); diff --git a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java index 8175d1dd0..69bcc67c5 100644 --- a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java +++ b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java @@ -46,9 +46,9 @@ class CandyGameTest { @Test void continueRoundTest() { var matrix = new Cell[2][2]; - var c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); - var c2 = new Candy("purple jelly", "jelly", Type.crushableCandy, 5); - var c3 = new Candy("green apple", "apple", Type.rewardFruit, 10); + var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5); + var c2 = new Candy("purple jelly", "jelly", Type.CRUSHABLE_CANDY, 5); + var c3 = new Candy("green apple", "apple", Type.REWARD_FRUIT, 10); matrix[0][0] = new Cell(c1, 0, 0); matrix[0][1] = new Cell(c2, 1, 0); matrix[1][0] = new Cell(c3, 0, 1); diff --git a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java index 18bca62bb..6d910e47c 100644 --- a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java +++ b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java @@ -36,8 +36,8 @@ class CellTest { @Test void interactTest() { - var c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); - var c2 = new Candy("green apple", "apple", Type.rewardFruit, 10); + var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5); + var c2 = new Candy("green apple", "apple", Type.REWARD_FRUIT, 10); var matrix = new Cell[4][4]; matrix[0][0] = new Cell(c1, 0, 0); matrix[0][1] = new Cell(c1, 1, 0); @@ -51,8 +51,8 @@ class CellTest { @Test void crushTest() { - var c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); - var c2 = new Candy("purple candy", "candy", Type.crushableCandy, 5); + var c1 = new Candy("green jelly", "jelly", Type.CRUSHABLE_CANDY, 5); + var c2 = new Candy("purple candy", "candy", Type.CRUSHABLE_CANDY, 5); var matrix = new Cell[4][4]; matrix[0][0] = new Cell(c1, 0, 0); matrix[1][0] = new Cell(c2, 0, 1); diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index cd6ce06f1..1fab10186 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -44,6 +44,11 @@ junit-vintage-engine test + + org.junit.jupiter + junit-jupiter-engine + test + org.mockito mockito-core diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/IUnitOfWork.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/IUnitOfWork.java index c44a696e3..e5e24817f 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/IUnitOfWork.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/IUnitOfWork.java @@ -29,9 +29,6 @@ package com.iluwatar.unitofwork; * @param Any generic entity */ public interface IUnitOfWork { - String INSERT = "INSERT"; - String DELETE = "DELETE"; - String MODIFY = "MODIFY"; /** * Any register new operation occurring on UnitOfWork is only going to be performed on commit. diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java index 73c1068b3..70433ed98 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/StudentRepository.java @@ -52,20 +52,20 @@ public class StudentRepository implements IUnitOfWork { @Override public void registerNew(Student student) { LOGGER.info("Registering {} for insert in context.", student.getName()); - register(student, IUnitOfWork.INSERT); + register(student, UnitActions.INSERT.getActionValue()); } @Override public void registerModified(Student student) { LOGGER.info("Registering {} for modify in context.", student.getName()); - register(student, IUnitOfWork.MODIFY); + register(student, UnitActions.MODIFY.getActionValue()); } @Override public void registerDeleted(Student student) { LOGGER.info("Registering {} for delete in context.", student.getName()); - register(student, IUnitOfWork.DELETE); + register(student, UnitActions.DELETE.getActionValue()); } private void register(Student student, String operation) { @@ -86,21 +86,21 @@ public class StudentRepository implements IUnitOfWork { return; } LOGGER.info("Commit started"); - if (context.containsKey(IUnitOfWork.INSERT)) { + if (context.containsKey(UnitActions.INSERT.getActionValue())) { commitInsert(); } - if (context.containsKey(IUnitOfWork.MODIFY)) { + if (context.containsKey(UnitActions.MODIFY.getActionValue())) { commitModify(); } - if (context.containsKey(IUnitOfWork.DELETE)) { + if (context.containsKey(UnitActions.DELETE.getActionValue())) { commitDelete(); } LOGGER.info("Commit finished."); } private void commitInsert() { - var studentsToBeInserted = context.get(IUnitOfWork.INSERT); + var studentsToBeInserted = context.get(UnitActions.INSERT.getActionValue()); for (var student : studentsToBeInserted) { LOGGER.info("Saving {} to database.", student.getName()); studentDatabase.insert(student); @@ -108,7 +108,7 @@ public class StudentRepository implements IUnitOfWork { } private void commitModify() { - var modifiedStudents = context.get(IUnitOfWork.MODIFY); + var modifiedStudents = context.get(UnitActions.MODIFY.getActionValue()); for (var student : modifiedStudents) { LOGGER.info("Modifying {} to database.", student.getName()); studentDatabase.modify(student); @@ -116,7 +116,7 @@ public class StudentRepository implements IUnitOfWork { } private void commitDelete() { - var deletedStudents = context.get(IUnitOfWork.DELETE); + var deletedStudents = context.get(UnitActions.DELETE.getActionValue()); for (var student : deletedStudents) { LOGGER.info("Deleting {} to database.", student.getName()); studentDatabase.delete(student); diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java new file mode 100644 index 000000000..b00d015a3 --- /dev/null +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java @@ -0,0 +1,18 @@ +package com.iluwatar.unitofwork; + +public enum UnitActions { + INSERT("INSERT"), + DELETE("DELETE"), + MODIFY("MODIFY") + ; + + private final String actionValue; + + UnitActions(String actionValue) { + this.actionValue = actionValue; + } + + public String getActionValue() { + return actionValue; + } +} diff --git a/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java b/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java index ecbe5fc53..2fbe37ccf 100644 --- a/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java +++ b/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java @@ -25,12 +25,14 @@ package com.iluwatar.unitofwork; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * AppTest */ public class AppTest { @Test - public void test() { - App.main(new String[]{}); + public void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/unit-of-work/src/test/java/com/iluwatar/unitofwork/StudentRepositoryTest.java b/unit-of-work/src/test/java/com/iluwatar/unitofwork/StudentRepositoryTest.java index cda2f6fca..6cf1e6e16 100644 --- a/unit-of-work/src/test/java/com/iluwatar/unitofwork/StudentRepositoryTest.java +++ b/unit-of-work/src/test/java/com/iluwatar/unitofwork/StudentRepositoryTest.java @@ -63,7 +63,7 @@ public class StudentRepositoryTest { studentRepository.registerNew(student1); studentRepository.registerNew(student2); - assertEquals(2, context.get(IUnitOfWork.INSERT).size()); + assertEquals(2, context.get(UnitActions.INSERT.getActionValue()).size()); verifyNoMoreInteractions(studentDatabase); } @@ -72,7 +72,7 @@ public class StudentRepositoryTest { studentRepository.registerDeleted(student1); studentRepository.registerDeleted(student2); - assertEquals(2, context.get(IUnitOfWork.DELETE).size()); + assertEquals(2, context.get(UnitActions.DELETE.getActionValue()).size()); verifyNoMoreInteractions(studentDatabase); } @@ -81,15 +81,15 @@ public class StudentRepositoryTest { studentRepository.registerModified(student1); studentRepository.registerModified(student2); - assertEquals(2, context.get(IUnitOfWork.MODIFY).size()); + assertEquals(2, context.get(UnitActions.MODIFY.getActionValue()).size()); verifyNoMoreInteractions(studentDatabase); } @Test public void shouldSaveAllLocalChangesToDb() { - context.put(IUnitOfWork.INSERT, List.of(student1)); - context.put(IUnitOfWork.MODIFY, List.of(student1)); - context.put(IUnitOfWork.DELETE, List.of(student1)); + context.put(UnitActions.INSERT.getActionValue(), List.of(student1)); + context.put(UnitActions.MODIFY.getActionValue(), List.of(student1)); + context.put(UnitActions.DELETE.getActionValue(), List.of(student1)); studentRepository.commit(); @@ -118,8 +118,8 @@ public class StudentRepositoryTest { @Test public void shouldNotInsertToDbIfNoRegisteredStudentsToBeCommitted() { - context.put(IUnitOfWork.MODIFY, List.of(student1)); - context.put(IUnitOfWork.DELETE, List.of(student1)); + context.put(UnitActions.MODIFY.getActionValue(), List.of(student1)); + context.put(UnitActions.DELETE.getActionValue(), List.of(student1)); studentRepository.commit(); @@ -128,8 +128,8 @@ public class StudentRepositoryTest { @Test public void shouldNotModifyToDbIfNotRegisteredStudentsToBeCommitted() { - context.put(IUnitOfWork.INSERT, List.of(student1)); - context.put(IUnitOfWork.DELETE, List.of(student1)); + context.put(UnitActions.INSERT.getActionValue(), List.of(student1)); + context.put(UnitActions.DELETE.getActionValue(), List.of(student1)); studentRepository.commit(); @@ -138,8 +138,8 @@ public class StudentRepositoryTest { @Test public void shouldNotDeleteFromDbIfNotRegisteredStudentsToBeCommitted() { - context.put(IUnitOfWork.INSERT, List.of(student1)); - context.put(IUnitOfWork.MODIFY, List.of(student1)); + context.put(UnitActions.INSERT.getActionValue(), List.of(student1)); + context.put(UnitActions.MODIFY.getActionValue(), List.of(student1)); studentRepository.commit(); diff --git a/update-method/pom.xml b/update-method/pom.xml index a89364328..78b89555a 100644 --- a/update-method/pom.xml +++ b/update-method/pom.xml @@ -38,6 +38,11 @@ junit junit + + org.junit.jupiter + junit-jupiter-engine + test + diff --git a/update-method/src/main/java/com/iluwatar/updatemethod/World.java b/update-method/src/main/java/com/iluwatar/updatemethod/World.java index 5b99050c8..37211abb1 100644 --- a/update-method/src/main/java/com/iluwatar/updatemethod/World.java +++ b/update-method/src/main/java/com/iluwatar/updatemethod/World.java @@ -88,6 +88,7 @@ public class World { * pattern. */ private void render() { + // Does Nothing } /** diff --git a/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java b/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java index 75c30470d..4849c4e62 100644 --- a/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java +++ b/update-method/src/test/java/com/iluwatar/updatemethod/AppTest.java @@ -25,11 +25,12 @@ package com.iluwatar.updatemethod; import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + public class AppTest { @Test - public void testMain() { - String[] args = {}; - App.main(args); + public void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/value-object/src/test/java/com/iluwatar/value/object/AppTest.java b/value-object/src/test/java/com/iluwatar/value/object/AppTest.java index c0e680ec4..39eaef28c 100644 --- a/value-object/src/test/java/com/iluwatar/value/object/AppTest.java +++ b/value-object/src/test/java/com/iluwatar/value/object/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.value.object; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } diff --git a/visitor/src/test/java/com/iluwatar/visitor/AppTest.java b/visitor/src/test/java/com/iluwatar/visitor/AppTest.java index c16f31195..45f7006a7 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/AppTest.java +++ b/visitor/src/test/java/com/iluwatar/visitor/AppTest.java @@ -25,13 +25,15 @@ package com.iluwatar.visitor; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + /** * Application test. */ -public class AppTest { +class AppTest { @Test - public void test() { - App.main(new String[]{}); + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); } } From 0d2c4abe5abb0de934b0b170eaeb86dc6814ff42 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 15 Aug 2020 17:53:37 +0000 Subject: [PATCH 241/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2435298e7..8b52c40fc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-122-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-123-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -251,6 +251,7 @@ This project is licensed under the terms of the MIT license.
Ashish Trivedi

💻
洪月阳

💻 +
xdvrx1

👀 From a1c96ede139f50816ec710f3c07795c5b0aa2830 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 15 Aug 2020 17:53:38 +0000 Subject: [PATCH 242/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7a9aa42c4..484dd303b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1111,6 +1111,15 @@ "contributions": [ "code" ] + }, + { + "login": "xdvrx1", + "name": "xdvrx1", + "avatar_url": "https://avatars0.githubusercontent.com/u/47092464?v=4", + "profile": "https://xdvrx1.github.io/", + "contributions": [ + "review" + ] } ], "contributorsPerLine": 4, From 7afb065a108895a122bc18e1d2313dc1a3f6b9b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 15 Aug 2020 20:58:59 +0300 Subject: [PATCH 243/285] Upgrade urm plugin to latest version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b3382795..0718ff045 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 2.3.2 1.3.2 1.19.0 - 1.4.8 + 2.0.0 https://sonarcloud.io iluwatar From 133ef52898287827ff6648e3a9261560cee258b0 Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Sat, 15 Aug 2020 22:19:27 +0400 Subject: [PATCH 244/285] Fixed an issue with the order of imports that was causing build failures. --- .../iluwatar/model/view/presenter/FileSelectorJFrame.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java index 1dd1bf818..f59bcdf6f 100644 --- a/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java +++ b/model-view-presenter/src/main/java/com/iluwatar/model/view/presenter/FileSelectorJFrame.java @@ -23,9 +23,13 @@ package com.iluwatar.model.view.presenter; +import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; +import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; + import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; + import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; @@ -35,10 +39,6 @@ import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; -import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; -import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; -import static javax.swing.WindowConstants.EXIT_ON_CLOSE; - /** * This class is the GUI implementation of the View component in the Model-View-Presenter pattern. */ From 00d06871f4841b676467bb933d7859713de0f306 Mon Sep 17 00:00:00 2001 From: Subhrodip Mohanta Date: Sun, 16 Aug 2020 12:42:08 +0530 Subject: [PATCH 245/285] updated workflows --- .github/workflows/{maven.yml => maven-ci.yml} | 10 ++- .github/workflows/maven-pr-builder.yml | 64 +++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) rename .github/workflows/{maven.yml => maven-ci.yml} (91%) create mode 100644 .github/workflows/maven-pr-builder.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven-ci.yml similarity index 91% rename from .github/workflows/maven.yml rename to .github/workflows/maven-ci.yml index d18cad280..914db3f4d 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven-ci.yml @@ -24,13 +24,11 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Java CI with Maven +name: Java CI on: push: branches: [ master ] - pull_request: - branches: [ master ] jobs: build: @@ -43,6 +41,12 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- # Some tests need screen access - name: Install xvfb run: sudo apt-get install xvfb diff --git a/.github/workflows/maven-pr-builder.yml b/.github/workflows/maven-pr-builder.yml new file mode 100644 index 000000000..ea5d3d703 --- /dev/null +++ b/.github/workflows/maven-pr-builder.yml @@ -0,0 +1,64 @@ +# +# The MIT License +# Copyright © 2014-2019 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. +# + +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Java PR Builder + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + # Some tests need screen access + - name: Install xvfb + run: sudo apt-get install xvfb + # SonarQube scan does not work for forked repositories + # See https://jira.sonarsource.com/browse/MMF-1371 + - name: Build with Maven + if: github.ref != 'refs/heads/master' + run: xvfb-run mvn clean verify + - name: Build with Maven and run SonarQube analysis + if: github.ref == 'refs/heads/master' + run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar + env: + # These two env variables are needed for sonar analysis + GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 79a6af703ec94e3719c05122e0c1c08768a877d6 Mon Sep 17 00:00:00 2001 From: Subhrodip Mohanta Date: Sun, 16 Aug 2020 12:49:21 +0530 Subject: [PATCH 246/285] updated copyright year to 2020 --- .github/workflows/maven-ci.yml | 2 +- .github/workflows/maven-pr-builder.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index 914db3f4d..a04b0021e 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -1,6 +1,6 @@ # # The MIT License -# Copyright © 2014-2019 Ilkka Seppälä +# Copyright © 2014-2020 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 diff --git a/.github/workflows/maven-pr-builder.yml b/.github/workflows/maven-pr-builder.yml index ea5d3d703..0384c326c 100644 --- a/.github/workflows/maven-pr-builder.yml +++ b/.github/workflows/maven-pr-builder.yml @@ -1,6 +1,6 @@ # # The MIT License -# Copyright © 2014-2019 Ilkka Seppälä +# Copyright © 2014-2020 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 From 57e45a329f23571544663a6e7b9c7133a4dcc731 Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Sun, 16 Aug 2020 22:35:15 +0400 Subject: [PATCH 247/285] Fixed a whitespace and spelling issue that was causing the test case to fail. --- extension-objects/src/main/java/concreteextensions/Soldier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension-objects/src/main/java/concreteextensions/Soldier.java b/extension-objects/src/main/java/concreteextensions/Soldier.java index 76ddbfd06..3ceaa7880 100644 --- a/extension-objects/src/main/java/concreteextensions/Soldier.java +++ b/extension-objects/src/main/java/concreteextensions/Soldier.java @@ -42,7 +42,7 @@ public class Soldier implements SoldierExtension { @Override public void soldierReady() { - LOGGER.info("[Solider] " + unit.getName() + " is ready!"); + LOGGER.info("[Soldier] " + unit.getName() + " is ready!"); } public SoldierUnit getUnit() { From 241f93f3ccd6d83b16006ede3c5241f5feae480a Mon Sep 17 00:00:00 2001 From: Subhrodip Mohanta Date: Mon, 17 Aug 2020 11:28:33 +0530 Subject: [PATCH 248/285] updated cache to v2 and removed SQ analysis --- .github/workflows/maven-ci.yml | 2 +- .github/workflows/maven-pr-builder.yml | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index a04b0021e..8a7f7a0bb 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -41,7 +41,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 - - uses: actions/cache@v1 + - uses: actions/cache@v2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/maven-pr-builder.yml b/.github/workflows/maven-pr-builder.yml index 0384c326c..1bdad0621 100644 --- a/.github/workflows/maven-pr-builder.yml +++ b/.github/workflows/maven-pr-builder.yml @@ -41,7 +41,7 @@ jobs: uses: actions/setup-java@v1 with: java-version: 11 - - uses: actions/cache@v1 + - uses: actions/cache@v2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -55,10 +55,3 @@ jobs: - name: Build with Maven if: github.ref != 'refs/heads/master' run: xvfb-run mvn clean verify - - name: Build with Maven and run SonarQube analysis - if: github.ref == 'refs/heads/master' - run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar - env: - # These two env variables are needed for sonar analysis - GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 89bda692f80b310e394219dbbb6b396f944db8c6 Mon Sep 17 00:00:00 2001 From: Bethan Palmer Date: Mon, 17 Aug 2020 07:47:30 +0100 Subject: [PATCH 249/285] Fix typo in README The log message in the Orcs class should say orcs instead of hobbits. This is correct in the code example but wrong in the README. --- observer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observer/README.md b/observer/README.md index e4b3cea76..d0ddf3c00 100644 --- a/observer/README.md +++ b/observer/README.md @@ -46,7 +46,7 @@ public class Orcs implements WeatherObserver { @Override public void update(WeatherType currentWeather) { - LOGGER.info("The hobbits are facing " + currentWeather.getDescription() + " weather now"); + LOGGER.info("The orcs are facing " + currentWeather.getDescription() + " weather now"); } } From 8c5740563dc5c1eb01c55bdcc919a70bb880d99d Mon Sep 17 00:00:00 2001 From: Subhrodip Mohanta Date: Mon, 17 Aug 2020 19:12:54 +0530 Subject: [PATCH 250/285] reverted the copyright year back to 2019 --- .github/workflows/maven-ci.yml | 2 +- .github/workflows/maven-pr-builder.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index 8a7f7a0bb..be0a74e9f 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -1,6 +1,6 @@ # # The MIT License -# Copyright © 2014-2020 Ilkka Seppälä +# Copyright © 2014-2019 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 diff --git a/.github/workflows/maven-pr-builder.yml b/.github/workflows/maven-pr-builder.yml index 1bdad0621..7e4f3670f 100644 --- a/.github/workflows/maven-pr-builder.yml +++ b/.github/workflows/maven-pr-builder.yml @@ -1,6 +1,6 @@ # # The MIT License -# Copyright © 2014-2020 Ilkka Seppälä +# Copyright © 2014-2019 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 From 353a2d9fcf294312816ccc1f091ff7e0937c16c3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:10:20 +0000 Subject: [PATCH 251/285] docs: update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b52c40fc..2169889dd 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ This project is licensed under the terms of the MIT license.
Ashish Trivedi

💻
洪月阳

💻 -
xdvrx1

👀 +
xdvrx1

👀 🤔 From d584404df6c011c854cb3e3025b0072d7d422ddb Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:10:21 +0000 Subject: [PATCH 252/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 484dd303b..4bdc6c011 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1118,7 +1118,8 @@ "avatar_url": "https://avatars0.githubusercontent.com/u/47092464?v=4", "profile": "https://xdvrx1.github.io/", "contributions": [ - "review" + "review", + "ideas" ] } ], From cfb58191ea58c12bb1060f6a4defa7e19ccae28e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:14:03 +0000 Subject: [PATCH 253/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2169889dd..36094b1db 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-123-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-124-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -252,6 +252,7 @@ This project is licensed under the terms of the MIT license.
Ashish Trivedi

💻
洪月阳

💻
xdvrx1

👀 🤔 +
Subhrodip Mohanta

💻 From 7f60f7be25f4d1c39279aa49acee7a8dd215ec3c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:14:04 +0000 Subject: [PATCH 254/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 4bdc6c011..6ea5a5de6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1121,6 +1121,15 @@ "review", "ideas" ] + }, + { + "login": "ohbus", + "name": "Subhrodip Mohanta", + "avatar_url": "https://avatars0.githubusercontent.com/u/13291222?v=4", + "profile": "http://subho.xyz", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 95e513b6ecffbc7a1fbd194c1908e0f9f9adf2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Mon, 17 Aug 2020 19:49:00 +0300 Subject: [PATCH 255/285] Edit readme --- visitor/README.md | 48 ++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/visitor/README.md b/visitor/README.md index c97e97120..75a032a47 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -9,13 +9,17 @@ tags: --- ## Intent -Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. + +Represent an operation to be performed on the elements of an object structure. Visitor lets you +define a new operation without changing the classes of the elements on which it operates. ## Explanation Real world example -> Consider a tree structure with army units. Commander has two sergeants under it and each sergeant has three soldiers under them. Given that the hierarchy implements the visitor pattern, we can easily create new objects that interact with the commander, sergeants, soldiers or all of them. +> Consider a tree structure with army units. Commander has two sergeants under it and each sergeant +> has three soldiers under them. Given that the hierarchy implements the visitor pattern, we can +> easily create new objects that interact with the commander, sergeants, soldiers or all of them. In plain words @@ -23,7 +27,10 @@ In plain words Wikipedia says -> In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying the structures. +> In object-oriented programming and software engineering, the visitor design pattern is a way of +> separating an algorithm from an object structure on which it operates. A practical result of this +> separation is the ability to add new operations to existing object structures without modifying +> the structures. **Programmatic Example** @@ -111,7 +118,7 @@ public class Soldier extends Unit { } ``` -And then some concrete visitors. +Here are then some concrete visitors. ```java public class CommanderVisitor implements UnitVisitor { @@ -175,32 +182,39 @@ public class SoldierVisitor implements UnitVisitor { } ``` -Finally we can show the power of visitors in action. +Finally, we can show the power of visitors in action. ```java commander.accept(new SoldierVisitor()); -// Greetings soldier -// Greetings soldier -// Greetings soldier -// Greetings soldier -// Greetings soldier -// Greetings soldier commander.accept(new SergeantVisitor()); -// Hello sergeant -// Hello sergeant commander.accept(new CommanderVisitor()); -// Good to see you commander +``` + +Program output: + +``` +Greetings soldier +Greetings soldier +Greetings soldier +Greetings soldier +Greetings soldier +Greetings soldier +Hello sergeant +Hello sergeant +Good to see you commander ``` ## Class diagram + ![alt text](./etc/visitor_1.png "Visitor") ## Applicability + Use the Visitor pattern when -* An object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes -* Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them -* The classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes +* An object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes. +* Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them. +* The classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes. ## Real world examples From ef43af3b2372026214512fa486c758ce98721567 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2020 16:42:02 +0000 Subject: [PATCH 256/285] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 36094b1db..225f14709 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-124-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-125-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -254,6 +254,9 @@ This project is licensed under the terms of the MIT license.
xdvrx1

👀 🤔
Subhrodip Mohanta

💻 + +
Bethan Palmer

💻 + From 6c7715ace6b15cf010a4540b862d2b961c6e91c9 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2020 16:42:03 +0000 Subject: [PATCH 257/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6ea5a5de6..712ae41c2 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1130,6 +1130,15 @@ "contributions": [ "code" ] + }, + { + "login": "nahteb", + "name": "Bethan Palmer", + "avatar_url": "https://avatars3.githubusercontent.com/u/13121570?v=4", + "profile": "https://github.com/nahteb", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 06f20570b637dd1c432b27b2ab8e7e041eb2754c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2020 16:45:37 +0000 Subject: [PATCH 258/285] docs: update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36094b1db..91db25047 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,7 @@ This project is licensed under the terms of the MIT license.
Ashish Trivedi

💻
洪月阳

💻
xdvrx1

👀 🤔 -
Subhrodip Mohanta

💻 +
Subhrodip Mohanta

💻 👀 From 31881f500dd6442c1b0e6413fb931d47b953d5aa Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Aug 2020 16:45:38 +0000 Subject: [PATCH 259/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6ea5a5de6..8894929f7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1128,7 +1128,8 @@ "avatar_url": "https://avatars0.githubusercontent.com/u/13291222?v=4", "profile": "http://subho.xyz", "contributions": [ - "code" + "code", + "review" ] } ], From 847585334c4edea23aa675cc6b18c40db14982e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 18 Aug 2020 20:07:47 +0300 Subject: [PATCH 260/285] Update README.md --- unit-of-work/README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/unit-of-work/README.md b/unit-of-work/README.md index 590f718d3..01aa8e5d7 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -11,21 +11,27 @@ tags: --- ## Intent -When a business transaction is completed, all the the updates are sent as one big unit of work to be persisted -in one go to minimize database round-trips. + +When a business transaction is completed, all the the updates are sent as one big unit of work to be +persisted in one go to minimize database round-trips. ## Explanation + Real world example -> We have a database containing student information. Administrators all over the country are constantly updating this information and it causes high load on the database server. To make the load more manageable we apply to Unit of Work pattern to send many small updates in batches. +> We have a database containing student information. Administrators all over the country are +> constantly updating this information and it causes high load on the database server. To make the +> load more manageable we apply to Unit of Work pattern to send many small updates in batches. In plain words -> Unit of Work merges many small database updates in single batch to optimize the number of round-trips. +> Unit of Work merges many small database updates in single batch to optimize the number of +> round-trips. [MartinFowler.com](https://martinfowler.com/eaaCatalog/unitOfWork.html) says -> Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems. +> Maintains a list of objects affected by a business transaction and coordinates the writing out of +> changes and the resolution of concurrency problems. **Programmatic Example** @@ -57,8 +63,9 @@ public class Student { } ``` -The essence of the implementation is the `StudentRepository` implementing the Unit of Work pattern. It maintains a map -of database operations (`context`) that need to be done and when `commit` is called it applies them in single batch. +The essence of the implementation is the `StudentRepository` implementing the Unit of Work pattern. +It maintains a map of database operations (`context`) that need to be done and when `commit` is +called it applies them in single batch. ```java public interface IUnitOfWork { @@ -160,7 +167,7 @@ public class StudentRepository implements IUnitOfWork { } ``` -Finally here's how we use the `StudentRepository` and `commit` the transaction. +Finally, here's how we use the `StudentRepository` and `commit` the transaction. ```java studentRepository.registerNew(ram); @@ -170,9 +177,11 @@ Finally here's how we use the `StudentRepository` and `commit` the transaction. ``` ## Class diagram + ![alt text](etc/unit-of-work.urm.png "unit-of-work") ## Applicability + Use the Unit Of Work pattern when * To optimize the time taken for database transactions. From 6921b0dce0b503529a6bd8983bde91279487522c Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Wed, 19 Aug 2020 13:27:08 +0400 Subject: [PATCH 261/285] Fixed checkstyle errors causing build failures. --- .../iluwatar/ambassador/RemoteService.java | 3 +- .../ambassador/RemoteServiceStatus.java | 47 ++++-- .../com/iluwatar/commander/Commander.java | 138 +++++++++--------- .../component/manager/AiComponentManager.java | 8 +- .../manager/PhysicsComponentManager.java | 8 +- .../manager/RenderComponentManager.java | 8 +- unit-of-work/pom.xml | 1 + .../java/com/iluwatar/unitofwork/App.java | 1 + .../com/iluwatar/unitofwork/UnitActions.java | 44 ++++-- .../java/com/iluwatar/unitofwork/AppTest.java | 1 + 10 files changed, 151 insertions(+), 108 deletions(-) diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java index 42b09d617..e2877b683 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteService.java @@ -74,6 +74,7 @@ public class RemoteService implements RemoteServiceInterface { } catch (InterruptedException e) { LOGGER.error("Thread sleep state interrupted", e); } - return waitTime <= THRESHOLD ? value * 10 : RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue(); + return waitTime <= THRESHOLD ? value * 10 + : RemoteServiceStatus.FAILURE.getRemoteServiceStatusValue(); } } diff --git a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java index f9faebd0e..5d830e0fc 100644 --- a/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java +++ b/ambassador/src/main/java/com/iluwatar/ambassador/RemoteServiceStatus.java @@ -1,23 +1,48 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.ambassador; /** * Holds information regarding the status of the Remote Service. * - * !Attention - This Enum replaces the integer value previously stored in {@link RemoteServiceInterface} - * as SonarCloud was identifying it as an issue. All test cases have been checked after changes, without failures. + *

This Enum replaces the integer value previously + * stored in {@link RemoteServiceInterface} as SonarCloud was identifying + * it as an issue. All test cases have been checked after changes, + * without failures.

*/ public enum RemoteServiceStatus { - FAILURE(-1) - ; + FAILURE(-1) + ; - private final long remoteServiceStatusValue; + private final long remoteServiceStatusValue; - RemoteServiceStatus(long remoteServiceStatusValue) { - this.remoteServiceStatusValue = remoteServiceStatusValue; - } + RemoteServiceStatus(long remoteServiceStatusValue) { + this.remoteServiceStatusValue = remoteServiceStatusValue; + } - public long getRemoteServiceStatusValue() { - return remoteServiceStatusValue; - } + public long getRemoteServiceStatusValue() { + return remoteServiceStatusValue; + } } diff --git a/commander/src/main/java/com/iluwatar/commander/Commander.java b/commander/src/main/java/com/iluwatar/commander/Commander.java index c2e124663..2909f9304 100644 --- a/commander/src/main/java/com/iluwatar/commander/Commander.java +++ b/commander/src/main/java/com/iluwatar/commander/Commander.java @@ -36,10 +36,10 @@ import com.iluwatar.commander.queue.QueueDatabase; import com.iluwatar.commander.queue.QueueTask; import com.iluwatar.commander.queue.QueueTask.TaskType; import com.iluwatar.commander.shippingservice.ShippingService; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; /** *

Commander pattern is used to handle all issues that can come up while making a @@ -171,10 +171,53 @@ public class Commander { var list = paymentService.exceptionsList; var t = new Thread(() -> { Retry.Operation op = (l) -> { - handlePaymentRetryOperation(order, l); + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to payment service," + + " trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating payment request.."); + } + throw l.remove(0); + } + if (order.paid.equals(PaymentStatus.TRYING)) { + var transactionId = paymentService.receiveRequest(order.price); + order.paid = PaymentStatus.DONE; + LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId); + if (!finalSiteMsgShown) { + LOG.info("Payment made successfully, thank you for shopping with us!!"); + finalSiteMsgShown = true; + } + sendSuccessMessage(order); + } }; Retry.HandleErrorIssue handleError = (o, err) -> { - handlePaymentErrorIssue(order, o, err); + if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) { + if (!finalSiteMsgShown) { + LOG.info("There was an error in payment. Your account/card details " + + "may have been incorrect. " + + "Meanwhile, your order has been converted to COD and will be shipped."); + finalSiteMsgShown = true; + } + LOG.error("Order " + order.id + ": Payment details incorrect, failed.."); + o.paid = PaymentStatus.NOT_DONE; + sendPaymentFailureMessage(o); + } else { + if (o.messageSent.equals(MessageSent.NONE_SENT)) { + if (!finalSiteMsgShown) { + LOG.info("There was an error in payment. We are on it, and will get back to you " + + "asap. Don't worry, your order has been placed and will be shipped."); + finalSiteMsgShown = true; + } + LOG.warn("Order " + order.id + ": Payment error, going to queue.."); + sendPaymentPossibleErrorMsg(o); + } + if (o.paid.equals(PaymentStatus.TRYING) && System + .currentTimeMillis() - o.createdTime < paymentTime) { + var qt = new QueueTask(o, TaskType.PAYMENT, -1); + updateQueue(qt); + } + } }; var r = new Retry<>(op, handleError, numOfRetries, retryDuration, e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); @@ -187,58 +230,6 @@ public class Commander { t.start(); } - private void handlePaymentRetryOperation(Order order, List l) throws Exception { - if (!l.isEmpty()) { - if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { - LOG.debug("Order " + order.id + ": Error in connecting to payment service," - + " trying again.."); - } else { - LOG.debug("Order " + order.id + ": Error in creating payment request.."); - } - throw l.remove(0); - } - if (order.paid.equals(PaymentStatus.TRYING)) { - var transactionId = paymentService.receiveRequest(order.price); - order.paid = PaymentStatus.DONE; - LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId); - - if (!finalSiteMsgShown) { - LOG.info("Payment made successfully, thank you for shopping with us!!"); - finalSiteMsgShown = true; - } - sendSuccessMessage(order); - } - } - - private void handlePaymentErrorIssue(Order order, Order o, Exception err) { - if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) { - if (!finalSiteMsgShown) { - LOG.info("There was an error in payment. Your account/card details " - + "may have been incorrect. " - + "Meanwhile, your order has been converted to COD and will be shipped."); - finalSiteMsgShown = true; - } - LOG.error("Order " + order.id + ": Payment details incorrect, failed.."); - o.paid = PaymentStatus.NOT_DONE; - sendPaymentFailureMessage(o); - } else { - if (o.messageSent.equals(MessageSent.NONE_SENT)) { - if (!finalSiteMsgShown) { - LOG.info("There was an error in payment. We are on it, and will get back to you " - + "asap. Don't worry, your order has been placed and will be shipped."); - finalSiteMsgShown = true; - } - LOG.warn("Order " + order.id + ": Payment error, going to queue.."); - sendPaymentPossibleErrorMsg(o); - } - if (o.paid.equals(PaymentStatus.TRYING) && System - .currentTimeMillis() - o.createdTime < paymentTime) { - var qt = new QueueTask(o, TaskType.PAYMENT, -1); - updateQueue(qt); - } - } - } - private void updateQueue(QueueTask qt) { if (System.currentTimeMillis() - qt.order.createdTime >= this.queueTime) { // since payment time is lesser than queuetime it would have already failed.. @@ -371,24 +362,24 @@ public class Commander { private Retry.Operation handleSuccessMessageRetryOperation(Order order) { return (l) -> { - if (!l.isEmpty()) { - if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { - LOG.debug("Order " + order.id + ": Error in connecting to messaging service " - + "(Payment Success msg), trying again.."); - } else { - LOG.debug("Order " + order.id + ": Error in creating Payment Success" - + " messaging request.."); - } - throw l.remove(0); + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to messaging service " + + "(Payment Success msg), trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating Payment Success" + + " messaging request.."); } - if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL) - && !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) { - var requestId = messagingService.receiveRequest(2); - order.messageSent = MessageSent.PAYMENT_SUCCESSFUL; - LOG.info("Order " + order.id + ": Payment Success message sent," - + " request Id: " + requestId); - } - }; + throw l.remove(0); + } + if (!order.messageSent.equals(MessageSent.PAYMENT_FAIL) + && !order.messageSent.equals(MessageSent.PAYMENT_SUCCESSFUL)) { + var requestId = messagingService.receiveRequest(2); + order.messageSent = MessageSent.PAYMENT_SUCCESSFUL; + LOG.info("Order " + order.id + ": Payment Success message sent," + + " request Id: " + requestId); + } + }; } private void sendPaymentFailureMessage(Order order) { @@ -483,7 +474,8 @@ public class Commander { } } - private void handlePaymentPossibleErrorMsgRetryOperation(Order order, List l) throws Exception { + private void handlePaymentPossibleErrorMsgRetryOperation(Order order, List l) + throws Exception { if (!l.isEmpty()) { if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { LOG.debug("Order " + order.id + ": Error in connecting to messaging service " diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java index 1baf99a3a..c85bd1e68 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java @@ -40,7 +40,7 @@ public class AiComponentManager { private final int numEntities; - private final Component[] AI_COMPONENTS = new AiComponent[MAX_ENTITIES]; + private final Component[] aiComponents = new AiComponent[MAX_ENTITIES]; public AiComponentManager(int numEntities) { this.numEntities = numEntities; @@ -51,7 +51,7 @@ public class AiComponentManager { */ public void start() { LOGGER.info("Start AI Game Component"); - IntStream.range(0, numEntities).forEach(i -> AI_COMPONENTS[i] = new AiComponent()); + IntStream.range(0, numEntities).forEach(i -> aiComponents[i] = new AiComponent()); } /** @@ -60,7 +60,7 @@ public class AiComponentManager { public void update() { LOGGER.info("Update AI Game Component"); IntStream.range(0, numEntities) - .filter(i -> AI_COMPONENTS.length > i && AI_COMPONENTS[i] != null) - .forEach(i -> AI_COMPONENTS[i].update()); + .filter(i -> aiComponents.length > i && aiComponents[i] != null) + .forEach(i -> aiComponents[i].update()); } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java index e5917979c..155793c88 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java @@ -40,7 +40,7 @@ public class PhysicsComponentManager { private final int numEntities; - private final Component[] PHYSICS_COMPONENTS = new PhysicsComponent[MAX_ENTITIES]; + private final Component[] physicsComponents = new PhysicsComponent[MAX_ENTITIES]; public PhysicsComponentManager(int numEntities) { this.numEntities = numEntities; @@ -51,7 +51,7 @@ public class PhysicsComponentManager { */ public void start() { LOGGER.info("Start Physics Game Component "); - IntStream.range(0, numEntities).forEach(i -> PHYSICS_COMPONENTS[i] = new PhysicsComponent()); + IntStream.range(0, numEntities).forEach(i -> physicsComponents[i] = new PhysicsComponent()); } @@ -62,7 +62,7 @@ public class PhysicsComponentManager { LOGGER.info("Update Physics Game Component "); // Process physics. IntStream.range(0, numEntities) - .filter(i -> PHYSICS_COMPONENTS.length > i && PHYSICS_COMPONENTS[i] != null) - .forEach(i -> PHYSICS_COMPONENTS[i].update()); + .filter(i -> physicsComponents.length > i && physicsComponents[i] != null) + .forEach(i -> physicsComponents[i].update()); } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java index b3522f908..be1d3c2e9 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java @@ -40,7 +40,7 @@ public class RenderComponentManager { private final int numEntities; - private final Component[] RENDER_COMPONENTS = new RenderComponent[MAX_ENTITIES]; + private final Component[] renderComponents = new RenderComponent[MAX_ENTITIES]; public RenderComponentManager(int numEntities) { this.numEntities = numEntities; @@ -51,7 +51,7 @@ public class RenderComponentManager { */ public void start() { LOGGER.info("Start Render Game Component "); - IntStream.range(0, numEntities).forEach(i -> RENDER_COMPONENTS[i] = new RenderComponent()); + IntStream.range(0, numEntities).forEach(i -> renderComponents[i] = new RenderComponent()); } @@ -62,7 +62,7 @@ public class RenderComponentManager { LOGGER.info("Update Render Game Component "); // Process Render. IntStream.range(0, numEntities) - .filter(i -> RENDER_COMPONENTS.length > i && RENDER_COMPONENTS[i] != null) - .forEach(i -> RENDER_COMPONENTS[i].render()); + .filter(i -> renderComponents.length > i && renderComponents[i] != null) + .forEach(i -> renderComponents[i].render()); } } diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index 1fab10186..0f8f0b21a 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -47,6 +47,7 @@ org.junit.jupiter junit-jupiter-engine + 5.0.0 test diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/App.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/App.java index a9e41dd7c..6caf1de49 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/App.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/App.java @@ -35,6 +35,7 @@ public class App { * * @param args no argument sent */ + public static void main(String[] args) { var ram = new Student(1, "Ram", "Street 9, Cupertino"); var shyam = new Student(2, "Shyam", "Z bridge, Pune"); diff --git a/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java b/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java index b00d015a3..36e738626 100644 --- a/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java +++ b/unit-of-work/src/main/java/com/iluwatar/unitofwork/UnitActions.java @@ -1,18 +1,40 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.unitofwork; public enum UnitActions { - INSERT("INSERT"), - DELETE("DELETE"), - MODIFY("MODIFY") - ; + INSERT("INSERT"), + DELETE("DELETE"), + MODIFY("MODIFY"); - private final String actionValue; + private final String actionValue; - UnitActions(String actionValue) { - this.actionValue = actionValue; - } + UnitActions(String actionValue) { + this.actionValue = actionValue; + } - public String getActionValue() { - return actionValue; - } + public String getActionValue() { + return actionValue; + } } diff --git a/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java b/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java index 2fbe37ccf..630bb1392 100644 --- a/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java +++ b/unit-of-work/src/test/java/com/iluwatar/unitofwork/AppTest.java @@ -31,6 +31,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; * AppTest */ public class AppTest { + @Test public void shouldExecuteWithoutException() { assertDoesNotThrow(() -> App.main(new String[]{})); From 860453b46b73d7e977196a28439f1c4b4dca3c64 Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Wed, 19 Aug 2020 23:14:37 +0400 Subject: [PATCH 262/285] Fixed JUnit tests causing build issues due to mixing JUnit 4 & JUnit 5 --- .../java/org/dirty/flag/DirtyFlagTest.java | 14 +++---- partial-response/pom.xml | 14 +++---- .../com/iluwatar/partialresponse/AppTest.java | 11 +++--- .../partialresponse/FieldJsonMapperTest.java | 19 +++++---- .../partialresponse/VideoResourceTest.java | 39 +++++++++---------- pom.xml | 7 ++++ 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java index 6a3274a45..d0c9079a6 100644 --- a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java +++ b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java @@ -23,29 +23,27 @@ package org.dirty.flag; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import com.iluwatar.dirtyflag.DataFetcher; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; /** * Application test */ -public class DirtyFlagTest { +class DirtyFlagTest { @Test - public void testIsDirty() { + void testIsDirty() { var df = new DataFetcher(); var countries = df.fetch(); - assertFalse(countries.isEmpty()); + Assertions.assertTrue(countries.isEmpty()); } @Test - public void testIsNotDirty() { + void testIsNotDirty() { var df = new DataFetcher(); df.fetch(); var countries = df.fetch(); - assertTrue(countries.isEmpty()); + Assertions.assertTrue(countries.isEmpty()); } } diff --git a/partial-response/pom.xml b/partial-response/pom.xml index eb094874f..fad5450d9 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -35,13 +35,15 @@ partial-response - - junit - junit - org.junit.vintage junit-vintage-engine + 5.4.0 + test + + + org.mockito + mockito-junit-jupiter test @@ -49,10 +51,6 @@ junit-jupiter-engine test - - org.mockito - mockito-core - diff --git a/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java b/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java index b00ee6861..c423355f5 100644 --- a/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java +++ b/partial-response/src/test/java/com/iluwatar/partialresponse/AppTest.java @@ -23,18 +23,17 @@ package com.iluwatar.partialresponse; -import org.junit.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; /** * Application test */ -public class AppTest { +class AppTest { @Test - public void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[]{})); + void shouldExecuteApplicationWithoutException() { + Assertions.assertDoesNotThrow(() -> App.main(new String[]{})); } } \ No newline at end of file diff --git a/partial-response/src/test/java/com/iluwatar/partialresponse/FieldJsonMapperTest.java b/partial-response/src/test/java/com/iluwatar/partialresponse/FieldJsonMapperTest.java index 57741c1d7..6bf5bf190 100644 --- a/partial-response/src/test/java/com/iluwatar/partialresponse/FieldJsonMapperTest.java +++ b/partial-response/src/test/java/com/iluwatar/partialresponse/FieldJsonMapperTest.java @@ -23,24 +23,23 @@ package com.iluwatar.partialresponse; -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * tests {@link FieldJsonMapper}. */ -public class FieldJsonMapperTest { - private FieldJsonMapper mapper; +class FieldJsonMapperTest { + private static FieldJsonMapper mapper; - @Before - public void setUp() { + @BeforeAll + static void setUp() { mapper = new FieldJsonMapper(); } @Test - public void shouldReturnJsonForSpecifiedFieldsInVideo() throws Exception { + void shouldReturnJsonForSpecifiedFieldsInVideo() throws Exception { var fields = new String[]{"id", "title", "length"}; var video = new Video( 2, "Godzilla Resurgence", 120, @@ -50,6 +49,6 @@ public class FieldJsonMapperTest { var jsonFieldResponse = mapper.toJson(video, fields); var expectedDetails = "{\"id\": 2,\"title\": \"Godzilla Resurgence\",\"length\": 120}"; - assertEquals(expectedDetails, jsonFieldResponse); + Assertions.assertEquals(expectedDetails, jsonFieldResponse); } } \ No newline at end of file diff --git a/partial-response/src/test/java/com/iluwatar/partialresponse/VideoResourceTest.java b/partial-response/src/test/java/com/iluwatar/partialresponse/VideoResourceTest.java index 252499803..dbd8e78dd 100644 --- a/partial-response/src/test/java/com/iluwatar/partialresponse/VideoResourceTest.java +++ b/partial-response/src/test/java/com/iluwatar/partialresponse/VideoResourceTest.java @@ -23,30 +23,29 @@ package com.iluwatar.partialresponse; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; /** * tests {@link VideoResource}. */ -@RunWith(MockitoJUnitRunner.class) -public class VideoResourceTest { +@ExtendWith(MockitoExtension.class) +class VideoResourceTest { @Mock - private FieldJsonMapper fieldJsonMapper; + private static FieldJsonMapper fieldJsonMapper; - private VideoResource resource; + private static VideoResource resource; - @Before - public void setUp() { + @BeforeAll + static void setUp() { var videos = Map.of( 1, new Video(1, "Avatar", 178, "epic science fiction film", "James Cameron", "English"), @@ -58,23 +57,23 @@ public class VideoResourceTest { } @Test - public void shouldGiveVideoDetailsById() throws Exception { + void shouldGiveVideoDetailsById() throws Exception { var actualDetails = resource.getDetails(1); var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178,\"description\": " + "\"epic science fiction film\",\"director\": \"James Cameron\",\"language\": \"English\",}"; - assertEquals(expectedDetails, actualDetails); + Assertions.assertEquals(expectedDetails, actualDetails); } @Test - public void shouldGiveSpecifiedFieldsInformationOfVideo() throws Exception { + void shouldGiveSpecifiedFieldsInformationOfVideo() throws Exception { var fields = new String[]{"id", "title", "length"}; var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}"; - when(fieldJsonMapper.toJson(any(Video.class), eq(fields))).thenReturn(expectedDetails); + Mockito.when(fieldJsonMapper.toJson(Matchers.any(Video.class), Matchers.eq(fields))).thenReturn(expectedDetails); var actualFieldsDetails = resource.getDetails(2, fields); - assertEquals(expectedDetails, actualFieldsDetails); + Assertions.assertEquals(expectedDetails, actualFieldsDetails); } } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9b3382795..e917304a8 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,7 @@ 1.3.2 1.19.0 1.4.8 + 3.5.0 https://sonarcloud.io iluwatar @@ -226,6 +227,12 @@ spring-webmvc ${spring.version} + + org.mockito + mockito-junit-jupiter + ${mockito-junit-jupiter.version} + test + com.h2database h2 From c35b98b4d74a17211850c42cf507bdd49eb39769 Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Thu, 20 Aug 2020 01:01:03 +0400 Subject: [PATCH 263/285] Fixed pom.xml issues within the dirty-flag and partial-response modules that were causing build failures. --- dirty-flag/pom.xml | 7 ++++++- partial-response/pom.xml | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index c014cd41e..372a637f1 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -31,7 +31,6 @@ java-design-patterns 1.23.0-SNAPSHOT - com.iluwatar dirty-flag 1.23.0-SNAPSHOT dirty-flag @@ -45,6 +44,12 @@ junit-jupiter-engine test + + org.mockito + mockito-junit-jupiter + 3.5.0 + test + diff --git a/partial-response/pom.xml b/partial-response/pom.xml index fad5450d9..d10a496dd 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -44,6 +44,7 @@ org.mockito mockito-junit-jupiter + 3.5.0 test From 885c8a6765b37f3a403b63b993d1996ae2a31e1b Mon Sep 17 00:00:00 2001 From: Toxic Dreamz Date: Thu, 20 Aug 2020 01:21:03 +0400 Subject: [PATCH 264/285] Fixed a test-case issue within the dirty-flag module. --- dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java index d0c9079a6..9af9664d6 100644 --- a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java +++ b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java @@ -36,7 +36,7 @@ class DirtyFlagTest { void testIsDirty() { var df = new DataFetcher(); var countries = df.fetch(); - Assertions.assertTrue(countries.isEmpty()); + Assertions.assertFalse(countries.isEmpty()); } @Test From 905b5dc6d86d0e346d6336a2c4e7dcea9e622a71 Mon Sep 17 00:00:00 2001 From: Michal Krzywanski Date: Fri, 21 Aug 2020 11:07:23 +0200 Subject: [PATCH 265/285] Implemented filterer pattern --- filterer/README.MD | 45 ++++++ filterer/etc/filterer.png | Bin 0 -> 141773 bytes filterer/etc/filterer.urm.puml | 132 ++++++++++++++++++ filterer/pom.xml | 76 ++++++++++ .../iluwatar/filterer/domain/Filterer.java | 36 +++++ .../com/iluwatar/filterer/issue/Issue.java | 49 +++++++ .../filterer/issue/IssueAwareText.java | 55 ++++++++ .../filterer/issue/IssuePosition.java | 76 ++++++++++ .../iluwatar/filterer/issue/IssueType.java | 26 ++++ .../issue/ProbabilisticIssueAwareText.java | 49 +++++++ .../filterer/issue/ProbableIssue.java | 35 +++++ .../iluwatar/filterer/issue/SimpleIssue.java | 79 +++++++++++ .../filterer/issue/SimpleIssueAwareText.java | 98 +++++++++++++ .../SimpleProbabilisticIssueAwareText.java | 101 ++++++++++++++ .../filterer/issue/SimpleProbableIssue.java | 70 ++++++++++ .../issue/SimpleIssueAwareTextTest.java | 52 +++++++ ...SimpleProbabilisticIssueAwareTextTest.java | 52 +++++++ pom.xml | 1 + 18 files changed, 1032 insertions(+) create mode 100644 filterer/README.MD create mode 100644 filterer/etc/filterer.png create mode 100644 filterer/etc/filterer.urm.puml create mode 100644 filterer/pom.xml create mode 100644 filterer/src/main/java/com/iluwatar/filterer/domain/Filterer.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java create mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java create mode 100644 filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java create mode 100644 filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java diff --git a/filterer/README.MD b/filterer/README.MD new file mode 100644 index 000000000..8a2526048 --- /dev/null +++ b/filterer/README.MD @@ -0,0 +1,45 @@ +--- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ +layout: pattern +title: Filterer Pattern +folder: filterer +permalink: /patterns/filterer/ +description: Design pattern that helps container-like objects to return filtered version of themselves.# short meta description that shows in Google search results +categories: + - Functional +tags: + - Extensibility +--- + +## Name / classification +Filterer Pattern + +## Intent +The intent of this design pattern is to to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves. + +## Explanation +The container-like object needs to have a method that returns an instance of `Filterer`. This helper interface gives +ability to covariantly specify a lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the container-like objects. + +## Class diagram +![Filterer](./etc/filterer.png "Filterer") + +## Applicability +Pattern can be used when working with container-like objects that use subtyping, instead of parametrizing(generics) for extensible class structure. +It enables you to easily extend filtering ability of container-like objects as business requirements change. + +## Tutorials +* [Article about Filterer pattern posted on it's author's blog](https://blog.tlinkowski.pl/2018/filterer-pattern/) +* [Application of Filterer pattern in domain of text analysis](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) + +## Known uses +One of the uses is present on the blog presented in this link. It presents how to use `Filterer` pattern to create text issue anaylyzer with support for test cases used for unit testing. + +## Consequences (the good and the bad, add criticism here) +Good : + * you can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes. + +Bad : + * covariant return types mixed with generics can be sometimes tricky + +## Credits +* Author of the pattern : [Tomasz Linkowski](https://tlinkowski.pl/) \ No newline at end of file diff --git a/filterer/etc/filterer.png b/filterer/etc/filterer.png new file mode 100644 index 0000000000000000000000000000000000000000..f86764aa32aa18b063105c8ab529c2d04747326c GIT binary patch literal 141773 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%0ALv#igQ8NZ|3?qHU^qD?G%J=d~i5NG+tY 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

pY19!`Gaxytl%FiSo0r1}x?B$#Xwa2HWdQ5vi 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 literal 0 HcmV?d00001 diff --git a/filterer/etc/filterer.urm.puml b/filterer/etc/filterer.urm.puml new file mode 100644 index 000000000..24060b6aa --- /dev/null +++ b/filterer/etc/filterer.urm.puml @@ -0,0 +1,132 @@ +@startuml +package com.iluwatar.filterer.domain { + interface Filterer { + + by(Predicate) : G {abstract} + } +} +package com.iluwatar.filterer.issue { + interface Issue { + + endOffset() : int {abstract} + + startOffset() : int {abstract} + + type() : IssueType {abstract} + } + interface IssueAwareText { + + filtered() : Filterer {abstract} + + issues() : List {abstract} + + text() : String {abstract} + } + class IssuePosition { + - endOffset : int + - startOffset : int + - IssuePosition(startOffset : int, endOffset : int) + ~ endOffset() : int + + equals(o : Object) : boolean + + hashCode() : int + + of(startOffset : int, endOffset : int) : IssuePosition {static} + ~ startOffset() : int + } + ~enum IssueType { + + GRAMMAR {static} + + SPELLING {static} + + valueOf(name : String) : IssueType {static} + + values() : IssueType[] {static} + } + interface IssueWiseText { + + filtered() : Filterer {abstract} + + issues() : List {abstract} + + text() : String {abstract} + } + interface ProbabilisticIssueAwareText { + + filtered() : Filterer {abstract} + + issues() : List {abstract} + } + interface ProbabilisticIssueWiseText { + + filtered() : Filterer {abstract} + + issues() : List {abstract} + } + interface ProbableIssue { + + probability() : double {abstract} + } + class SimpleIssue { + - issuePosition : IssuePosition + - issueType : IssueType + ~ SimpleIssue(issuePosition : IssuePosition, issueType : IssueType) + + endOffset() : int + + equals(o : Object) : boolean + + hashCode() : int + + startOffset() : int + + type() : IssueType + } + class SimpleIssueAwareText { + - issues : ImmutableList + - text : String + ~ SimpleIssueAwareText(text : String, issues : List) + + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : IssueAwareText + - filteredItems(predicate : Predicate) : ImmutableList + + hashCode() : int + + issues() : List + + text() : String + } + class SimpleIssueWiseText { + - issues : ImmutableList + - text : String + + SimpleIssueWiseText(text : String, issues : List) + + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : IssueWiseText + - filteredItems(predicate : Predicate) : ImmutableList + + hashCode() : int + + issues() : List + + text() : String + } + class SimpleProbabilisticIssueAwareText { + - issues : ImmutableList + - text : String + ~ SimpleProbabilisticIssueAwareText(text : String, issues : List) + + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : ProbabilisticIssueAwareText + - filteredItems(predicate : Predicate) : ImmutableList + + hashCode() : int + + issues() : List + + text() : String + } + class SimpleProbabilisticIssueWiseText { + - issues : ImmutableList + - text : String + + SimpleProbabilisticIssueWiseText(text : String, issues : List) + + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : ProbabilisticIssueWiseText + - filteredItems(predicate : Predicate) : ImmutableList + + hashCode() : int + + issues() : List + + text() : String + } + class SimpleProbableIssue { + - probability : double + ~ SimpleProbableIssue(issuePosition : IssuePosition, issueType : IssueType, probability : double) + + equals(o : Object) : boolean + + hashCode() : int + + probability() : double + } +} +SimpleIssueWiseText --> "-issues" Issue +SimpleProbabilisticIssueAwareText --> "-issues" ProbableIssue +SimpleIssue --> "-issueType" IssueType +SimpleIssueAwareText --> "-issues" Issue +SimpleProbabilisticIssueWiseText --> "-issues" ProbableIssue +SimpleIssue --> "-issuePosition" IssuePosition +ProbabilisticIssueAwareText --|> IssueAwareText +ProbabilisticIssueWiseText --|> IssueWiseText +ProbableIssue --|> Issue +SimpleIssue ..|> Issue +SimpleIssueAwareText ..|> IssueAwareText +SimpleIssueWiseText ..|> IssueWiseText +SimpleProbabilisticIssueAwareText ..|> ProbabilisticIssueAwareText +SimpleProbabilisticIssueWiseText ..|> ProbabilisticIssueWiseText +SimpleProbableIssue ..|> ProbableIssue +SimpleProbableIssue --|> SimpleIssue +@enduml \ No newline at end of file diff --git a/filterer/pom.xml b/filterer/pom.xml new file mode 100644 index 000000000..24dae571e --- /dev/null +++ b/filterer/pom.xml @@ -0,0 +1,76 @@ + + + + + java-design-patterns + com.iluwatar + 1.23.0-SNAPSHOT + + 4.0.0 + + filterer + + + + com.google.guava + guava + 29.0-jre + + + org.junit.jupiter + junit-jupiter-api + 5.6.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + org.assertj + assertj-core + 3.16.1 + test + + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + + \ No newline at end of file diff --git a/filterer/src/main/java/com/iluwatar/filterer/domain/Filterer.java b/filterer/src/main/java/com/iluwatar/filterer/domain/Filterer.java new file mode 100644 index 000000000..17970c115 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/domain/Filterer.java @@ -0,0 +1,36 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.domain; + +import java.util.function.Predicate; + +/** + * Filterer helper interface. + * @param type of the container-like object. + * @param type of the elements contained within this container-like object. + */ +@FunctionalInterface +public interface Filterer { + G by(Predicate predicate); +} \ No newline at end of file diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java b/filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java new file mode 100644 index 000000000..957ade6e5 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +/** + * Represents an issue that can be detected in given text. + */ +public interface Issue { + /** + * Returns starting position where the issue begins. + * + * @return value representing starting position of the issue. + */ + int startOffset(); + + /** + * Returns ending position where the issue ends. + * + * @return value representing ending position of the issue. + */ + int endOffset(); + + /** + * Returns issue type. + * @return {@link IssueType} + */ + IssueType type(); +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java new file mode 100644 index 000000000..8141ae849 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java @@ -0,0 +1,55 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import com.iluwatar.filterer.domain.Filterer; + +import java.util.List; + +/** + * Represents text that is aware of issues that are present in it. + */ +public interface IssueAwareText { + + /** + * Returns the analyzed text. + * + * @return the analyzed text. + */ + String text(); + + /** + * Returns list of issues for this text. + * @return list of issues for this text. + */ + List issues(); + + /** + * Returns the instance of {@link Filterer} helper interface that allows to covariantly + * specify lower bound for predicate that we want to filter by. + * @return an instance of {@link Filterer} helper interface. + */ + Filterer filtered(); + +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java b/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java new file mode 100644 index 000000000..a771c1a82 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java @@ -0,0 +1,76 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import java.util.Objects; + +/** + * Represents position of an issue. Takes starting and ending offset of issue in given text. + */ +public final class IssuePosition { + + private final int startOffset; + private final int endOffset; + + /** + * Factory method for constructing `IssuePosition` instances. + * @param startOffset starting offset of where the issue begins. + * @param endOffset ending offset of where the issue ends. + * @return new IssuePosition instance. + */ + public static IssuePosition of(final int startOffset, final int endOffset) { + return new IssuePosition(startOffset, endOffset); + } + + private IssuePosition(int startOffset, int endOffset) { + this.startOffset = startOffset; + this.endOffset = endOffset; + } + + int startOffset() { + return startOffset; + } + + int endOffset() { + return endOffset; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + IssuePosition that = (IssuePosition) o; + return startOffset == that.startOffset + && endOffset == that.endOffset; + } + + @Override + public int hashCode() { + return Objects.hash(startOffset, endOffset); + } +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java b/filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java new file mode 100644 index 000000000..ee2c12ce5 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java @@ -0,0 +1,26 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +enum IssueType { GRAMMAR, SPELLING } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java new file mode 100644 index 000000000..da15bdd99 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java @@ -0,0 +1,49 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import com.iluwatar.filterer.domain.Filterer; + +import java.util.List; + +/** + * Represents text that is aware of it's issues with given probability of their occurrence. + */ +public interface ProbabilisticIssueAwareText extends IssueAwareText { + + /** + * {@inheritDoc} + * @return + */ + @Override + List issues(); + + /** + * {@inheritDoc} + * @return + */ + @Override + Filterer filtered(); +} + diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java b/filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java new file mode 100644 index 000000000..ccb047fa4 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java @@ -0,0 +1,35 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +/** + * Represents issue that is an issue with given probability. + */ +public interface ProbableIssue extends Issue { + /** + * Returns probability of occurrence of given issue. + * @return probability of occurrence of given issue. + */ + double probability(); +} \ No newline at end of file diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java new file mode 100644 index 000000000..fde5b8d8e --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import java.util.Objects; + +public class SimpleIssue implements Issue { + + private final IssuePosition issuePosition; + private final IssueType issueType; + + SimpleIssue(final IssuePosition issuePosition, IssueType issueType) { + this.issuePosition = issuePosition; + this.issueType = issueType; + } + + /** + * {@inheritDoc} + */ + @Override + public int startOffset() { + return issuePosition.startOffset(); + } + + /** + * {@inheritDoc} + */ + @Override + public int endOffset() { + return issuePosition.endOffset(); + } + + /** + * {@inheritDoc} + */ + @Override + public IssueType type() { + return issueType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SimpleIssue that = (SimpleIssue) o; + return issuePosition.equals(that.issuePosition) + && issueType == that.issueType; + } + + @Override + public int hashCode() { + return Objects.hash(issuePosition, issueType); + } +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java new file mode 100644 index 000000000..c654a3aaa --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java @@ -0,0 +1,98 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import com.google.common.collect.ImmutableList; +import com.iluwatar.filterer.domain.Filterer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * {@inheritDoc} + */ +public class SimpleIssueAwareText implements IssueAwareText { + + private final String text; + private final ImmutableList issues; + + SimpleIssueAwareText(final String text, final List issues) { + this.text = text; + this.issues = ImmutableList.copyOf(issues); + } + + /** + * {@inheritDoc} + */ + @Override + public String text() { + return text; + } + + /** + * {@inheritDoc} + */ + @Override + public List issues() { + return new ArrayList<>(issues); + } + + /** + * {@inheritDoc} + */ + @Override + public Filterer filtered() { + return this::filteredGroup; + } + + private IssueAwareText filteredGroup(Predicate predicate) { + return new SimpleIssueAwareText(this.text, filteredItems(predicate)); + } + + private ImmutableList filteredItems(Predicate predicate) { + return this.issues.stream() + .filter(predicate) + .collect(ImmutableList.toImmutableList()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SimpleIssueAwareText that = (SimpleIssueAwareText) o; + return text.equals(that.text) + && issues.equals(that.issues); + } + + @Override + public int hashCode() { + return Objects.hash(text, issues); + } +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java new file mode 100644 index 000000000..e1b4afc82 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java @@ -0,0 +1,101 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import com.google.common.collect.ImmutableList; +import com.iluwatar.filterer.domain.Filterer; + +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; + +/** + * {@inheritDoc} + */ +public class SimpleProbabilisticIssueAwareText implements ProbabilisticIssueAwareText { + + private final String text; + private final ImmutableList issues; + + SimpleProbabilisticIssueAwareText(final String text, final List issues) { + this.text = text; + this.issues = ImmutableList.copyOf(issues); + } + + /** + * {@inheritDoc} + */ + @Override + public String text() { + return text; + } + + /** + * {@inheritDoc} + */ + @Override + public List issues() { + return issues; + } + + /** + * {@inheritDoc} + */ + @Override + public Filterer filtered() { + return this::filteredGroup; + } + + private ProbabilisticIssueAwareText filteredGroup( + final Predicate predicate + ) { + return new SimpleProbabilisticIssueAwareText(this.text, filteredItems(predicate)); + } + + private ImmutableList filteredItems( + final Predicate predicate + ) { + return this.issues.stream() + .filter(predicate) + .collect(ImmutableList.toImmutableList()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SimpleProbabilisticIssueAwareText that = (SimpleProbabilisticIssueAwareText) o; + return text.equals(that.text) + && issues.equals(that.issues); + } + + @Override + public int hashCode() { + return Objects.hash(text, issues); + } +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java new file mode 100644 index 000000000..2b7672256 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java @@ -0,0 +1,70 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import java.util.Objects; + +/** + * {@inheritDoc} + */ +public class SimpleProbableIssue extends SimpleIssue implements ProbableIssue { + + private final double probability; + + SimpleProbableIssue(final IssuePosition issuePosition, + final IssueType issueType, + final double probability + ) { + super(issuePosition, issueType); + this.probability = probability; + } + + /** + * {@inheritDoc} + */ + @Override + public double probability() { + return probability; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + SimpleProbableIssue that = (SimpleProbableIssue) o; + return Double.compare(that.probability, probability) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), probability); + } +} diff --git a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java b/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java new file mode 100644 index 000000000..1278128ae --- /dev/null +++ b/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java @@ -0,0 +1,52 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class SimpleIssueAwareTextTest { + + @Test + void shouldFilterByStartOffset() { + //given + SimpleIssue spellingIssue = new SimpleIssue(IssuePosition.of(4, 5), IssueType.SPELLING); + SimpleIssue grammarIssue = new SimpleIssue(IssuePosition.of(8, 12), IssueType.GRAMMAR); + List issues = List.of(spellingIssue, grammarIssue); + + SimpleIssueAwareText simpleIssueWiseText = new SimpleIssueAwareText("I mihgt gone there", issues); + + //when + IssueAwareText filtered = simpleIssueWiseText.filtered() + .by(issue1 -> issue1.startOffset() == 4); + + //then + assertThat(filtered.issues()).hasSize(1); + assertThat(filtered.issues()).element(0).isEqualTo(spellingIssue); + } + +} diff --git a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java b/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java new file mode 100644 index 000000000..142415111 --- /dev/null +++ b/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java @@ -0,0 +1,52 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer.issue; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class SimpleProbabilisticIssueAwareTextTest { + + @Test + void shouldFilterByProbability() { + //given + ProbableIssue spellingIssue = new SimpleProbableIssue(IssuePosition.of(4, 5), IssueType.SPELLING, 100); + ProbableIssue grammarIssue = new SimpleProbableIssue(IssuePosition.of(8, 12), IssueType.GRAMMAR, 99); + List issues = List.of(spellingIssue, grammarIssue); + + SimpleProbabilisticIssueAwareText simpleIssueWiseText = new SimpleProbabilisticIssueAwareText("I mihgt gone there", issues); + + //when + ProbabilisticIssueAwareText filtered = simpleIssueWiseText.filtered() + .by(issue1 -> Double.compare(issue1.probability(), 99) == 0); + + //then + assertThat(filtered.issues()).hasSize(1); + assertThat(filtered.issues()).element(0).isEqualTo(grammarIssue); + } + +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0718ff045..1e34bcb67 100644 --- a/pom.xml +++ b/pom.xml @@ -193,6 +193,7 @@ strangler arrange-act-assert transaction-script + filterer From b388020fc0f42badd2af207e1440cb5f077f6d31 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2020 14:34:23 +0000 Subject: [PATCH 266/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 355744159..69f417574 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-125-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-126-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -256,6 +256,7 @@ This project is licensed under the terms of the MIT license.
Bethan Palmer

💻 +
Toxic Dreamz

💻 From 7f09cd5b2d232cf267c5f9d3b69c7699fb8240eb Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2020 14:34:24 +0000 Subject: [PATCH 267/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fa325716e..fadd92bc9 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1140,6 +1140,15 @@ "contributions": [ "code" ] + }, + { + "login": "ToxicDreamz", + "name": "Toxic Dreamz", + "avatar_url": "https://avatars0.githubusercontent.com/u/45225562?v=4", + "profile": "https://github.com/ToxicDreamz", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From a2ae5d1324386b24aaf944e65304f4ef60481697 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2020 15:00:48 +0000 Subject: [PATCH 268/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69f417574..4691b19b4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) -[![All Contributors](https://img.shields.io/badge/all_contributors-126-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-127-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -257,6 +257,7 @@ This project is licensed under the terms of the MIT license.
Bethan Palmer

💻
Toxic Dreamz

💻 +
Edy Cu Tjong

📖 From 0529b77abb677dda5ded898aa46c9d1c769e0718 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2020 15:00:49 +0000 Subject: [PATCH 269/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index fadd92bc9..b968e8c31 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1149,6 +1149,15 @@ "contributions": [ "code" ] + }, + { + "login": "edycutjong", + "name": "Edy Cu Tjong", + "avatar_url": "https://avatars1.githubusercontent.com/u/1098102?v=4", + "profile": "http://www.edycutjong.com", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 4, From 4068d1feadfd03fe683b6157aa1e13fa0f64e495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 22 Aug 2020 14:03:21 +0300 Subject: [PATCH 270/285] Update sonar badges --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4691b19b4..b0e297f82 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,9 @@ ![Java CI with Maven](https://github.com/iluwatar/java-design-patterns/workflows/Java%20CI%20with%20Maven/badge.svg) [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md) +[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=ncloc)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) [![All Contributors](https://img.shields.io/badge/all_contributors-127-orange.svg?style=flat-square)](#contributors-) From 61b95c294be022b19d48f457ee459610e666dec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 22 Aug 2020 14:49:56 +0300 Subject: [PATCH 271/285] Update github token --- .github/workflows/maven-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index be0a74e9f..9281c0f3d 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -60,5 +60,5 @@ jobs: run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar env: # These two env variables are needed for sonar analysis - GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} From 61a819aab8de2c9dce268815f641941bd45e18e7 Mon Sep 17 00:00:00 2001 From: Michal Krzywanski Date: Sat, 22 Aug 2020 17:53:09 +0200 Subject: [PATCH 272/285] Added fixes after review. Changed example pattern application to threat detection domain --- filterer/README.MD | 170 +++++++++++++++- filterer/etc/filterer.png | Bin 141773 -> 130820 bytes filterer/etc/filterer.urm.puml | 188 +++++++----------- filterer/pom.xml | 29 ++- .../main/java/com/iluwatar/filterer/App.java | 111 +++++++++++ .../filterer/issue/IssuePosition.java | 76 ------- .../ProbabilisticThreatAwareSystem.java} | 10 +- .../ProbableThreat.java} | 10 +- ...SimpleProbabilisticThreatAwareSystem.java} | 58 +++--- .../SimpleProbableThreat.java} | 23 ++- .../SimpleThreat.java} | 56 ++++-- .../SimpleThreatAwareSystem.java} | 43 ++-- .../{issue/Issue.java => threat/Threat.java} | 24 +-- .../ThreatAwareSystem.java} | 20 +- .../IssueType.java => threat/ThreatType.java} | 4 +- .../java/com/iluwatar/filterer/AppTest.java | 33 +++ ...leProbabilisticThreatAwareSystemTest.java} | 25 ++- .../SimpleThreatAwareSystemTest.java} | 28 ++- 18 files changed, 572 insertions(+), 336 deletions(-) create mode 100644 filterer/src/main/java/com/iluwatar/filterer/App.java delete mode 100644 filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java rename filterer/src/main/java/com/iluwatar/filterer/{issue/ProbabilisticIssueAwareText.java => threat/ProbabilisticThreatAwareSystem.java} (79%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/ProbableIssue.java => threat/ProbableThreat.java} (81%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/SimpleProbabilisticIssueAwareText.java => threat/SimpleProbabilisticThreatAwareSystem.java} (54%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/SimpleProbableIssue.java => threat/SimpleProbableThreat.java} (74%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/SimpleIssue.java => threat/SimpleThreat.java} (59%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/SimpleIssueAwareText.java => threat/SimpleThreatAwareSystem.java} (63%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/Issue.java => threat/Threat.java} (71%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/IssueAwareText.java => threat/ThreatAwareSystem.java} (78%) rename filterer/src/main/java/com/iluwatar/filterer/{issue/IssueType.java => threat/ThreatType.java} (92%) create mode 100644 filterer/src/test/java/com/iluwatar/filterer/AppTest.java rename filterer/src/test/java/com/iluwatar/filterer/{issue/SimpleProbabilisticIssueAwareTextTest.java => threat/SimpleProbabilisticThreatAwareSystemTest.java} (60%) rename filterer/src/test/java/com/iluwatar/filterer/{issue/SimpleIssueAwareTextTest.java => threat/SimpleThreatAwareSystemTest.java} (62%) diff --git a/filterer/README.MD b/filterer/README.MD index 8a2526048..3281e9ecc 100644 --- a/filterer/README.MD +++ b/filterer/README.MD @@ -1,6 +1,6 @@ --- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ layout: pattern -title: Filterer Pattern +title: Filterer folder: filterer permalink: /patterns/filterer/ description: Design pattern that helps container-like objects to return filtered version of themselves.# short meta description that shows in Google search results @@ -11,15 +11,173 @@ tags: --- ## Name / classification -Filterer Pattern +Filterer ## Intent The intent of this design pattern is to to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves. ## Explanation -The container-like object needs to have a method that returns an instance of `Filterer`. This helper interface gives +Real world example + +> We are designing a threat(malware) detection system. We can have different types of threats and systems. We have a requirement that +> system should be aware of threats that are present in it. In the design we have to take into consideration that new Threat types can be +> added later. Also there is a requirement that a system can filter itself based on the threats that it possesses (system acts as container-like object for threats). +> + +In plain words + +> We need to be able to filter different types of systems(container-like objects) based on properties of Threats that they contain. +> Adding new properties for Threats should be easy (we still need the ability to filter by those new properties). + +**Programmatic Example** + +To model the threat detection example presented above we introduce `Threat` and `ThreatAwareSystem` interfaces. + +```java +public interface Threat { + String name(); + int id(); + ThreatType type(); +} + +public interface ThreatAwareSystem { + String systemId(); + List threats(); + Filterer filtered(); + +} +``` +Notice the `filtered` method that returns instance of `Filterer` interface which is defined as : +```java +@FunctionalInterface +public interface Filterer { + G by(Predicate predicate); +} +``` +it is used to fulfill the requirement for system to be able to filter itself based on threat properties. +The container-like object (`ThreatAwareSystem` in our case) needs to have a method that returns an instance of `Filterer`. This helper interface gives ability to covariantly specify a lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the container-like objects. +In our example we will be able to pass a predicate that takes `? extends Threat` object and return `? extends ThreatAwareSystem` +from `Filtered::by` method. A simple implementation of `ThreadAwareSystem` : +```java +public class SimpleThreatAwareSystem implements ThreatAwareSystem { + + private final String systemId; + private final ImmutableList issues; + + public SimpleThreatAwareSystem(final String systemId, final List issues) { + this.systemId = systemId; + this.issues = ImmutableList.copyOf(issues); + } + + @Override + public String systemId() { + return systemId; + } + + @Override + public List threats() { + return new ArrayList<>(issues); + } + + @Override + public Filterer filtered() { + return this::filteredGroup; + } + + private ThreatAwareSystem filteredGroup(Predicate predicate) { + return new SimpleThreatAwareSystem(this.systemId, filteredItems(predicate)); + } + + private List filteredItems(Predicate predicate) { + return this.issues.stream() + .filter(predicate) + .collect(Collectors.toList()); + } +} +``` +the `filtered` method is overridden to filter the threats list by given predicate. + +Now if we introduce new subtype of `Thread` interface that adds probability with which given thread can appear : +```java +public interface ProbableThreat extends Threat { + double probability(); +} +``` +we can also introduce a new interface that represents a system that is aware of threats with their probabilities : +````java +public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem { + @Override + List threats(); + + @Override + Filterer filtered(); +} +```` +Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify different return covariant type +by specifing different generic types. Our interfaces are clean and not cluttered by default implementations. We +we will be able to filter `ProbabilisticThreatAwareSystem` by `ProbableThreat` properties : +```java +public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem { + + private final String systemId; + private final ImmutableList threats; + + public SimpleProbabilisticThreatAwareSystem(final String systemId, final List threats) { + this.systemId = systemId; + this.threats = ImmutableList.copyOf(threats); + } + + @Override + public String systemId() { + return systemId; + } + + @Override + public List threats() { + return threats; + } + + @Override + public Filterer filtered() { + return this::filteredGroup; + } + + private ProbabilisticThreatAwareSystem filteredGroup(final Predicate predicate) { + return new SimpleProbabilisticThreatAwareSystem(this.systemId, filteredItems(predicate)); + } + + private List filteredItems(final Predicate predicate) { + return this.threats.stream() + .filter(predicate) + .collect(Collectors.toList()); + } +} +``` + +Now if we want filter `ThreatAwareSystem` by threat type we can do : +```java +Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); +Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); +List threats = List.of(rootkit, trojan); + +ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); + +ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() + .by(threat -> threat.type() == ThreatType.ROOTKIT); +``` +or if we want to filter `ProbabilisticThreatAwareSystem` : +```java +ProbableThreat malwareTroyan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99); +ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8); +List probableThreats = List.of(malwareTroyan, rootkit); + +ProbabilisticThreatAwareSystem simpleProbabilisticThreatAwareSystem =new SimpleProbabilisticThreatAwareSystem("System-1", probableThreats); + +ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered() + .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); +``` ## Class diagram ![Filterer](./etc/filterer.png "Filterer") @@ -34,11 +192,11 @@ It enables you to easily extend filtering ability of container-like objects as b ## Known uses One of the uses is present on the blog presented in this link. It presents how to use `Filterer` pattern to create text issue anaylyzer with support for test cases used for unit testing. -## Consequences (the good and the bad, add criticism here) -Good : +## Consequences +Pros : * you can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes. -Bad : +Cons : * covariant return types mixed with generics can be sometimes tricky ## Credits diff --git a/filterer/etc/filterer.png b/filterer/etc/filterer.png index f86764aa32aa18b063105c8ab529c2d04747326c..6a6eb059b92d4bd0cc54d3d0df87cdff8eca01bb 100644 GIT binary patch literal 130820 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 z

f9pFXN}2->Zq<;c?8CCwtW4>{8bS=o=?5f3M2W~~jllZ`5wgNngqu-^||-^ec! zk0pX9yycV9c0eQA1)E1ZrNoeC*vmGu!c)zjky>>rq8iDwNBMXSmpwpTUBRym@fGUffPw=Tu5}llud@vx6UvFyrg3qZ3}f@>l}{%-`RD zu8KYPp+kb&Gi$Ls4u4Qub2I#$2S56=PS|k!+bWIycmb7M?@SHt&;5CM>DX2g&h}JB z9>w<<=;(3^?+4Nn3waFj&Fhz;?5mRxS)1yf0=|ih!S!GvUuq4c*4^oPG2qVSX&0>w zMx1>Cm23DY$NZ(~=QmAIyq`G?rUkJ|r(j$G`LDL2C&K0D*()f2{YGNy3^t^ zfFWbYj3A=4oiv1|pZpL4=;#KYIlX}uU=SeG8|8b}G*oY258cM!llRoGM(2u-k0-?$ zZJ(dV4YhN!F3ahir%YLpkJo^gH~7uvtX%rCp&TfF<=8SqJLWx(@S(=n<*ft) zH)jSLupYJ%AEsKpYrzqq6JbI3z4xuh@^WR8wZmaR*=cG_^ISZ_{_Wc=On3>2NX=$9 z@^RSe27r?w6)0+a@P+iyMr^e>0DGTjyhy?MzHt7a&vLX_wSm(jX+oP7J{0%{a>2x~ z1Jxh@^D#dC62Sa5D);@vJ6bCiujM38LO@Uz(5vH;f2cqJDSwfoWE%&+iD<9LWfg0Z zPikxtknUGzDT-2o!ujcXMmJhg%zVZsXmp%kzP9%DIn~uYeS(OxxGdS!u3f^eF3G-= zOG?a}Wu-G29Q^SPl-1iqyc`xg-sj1aC3Pap1jq)8H~9HpY1er83YJ(DsjqwMG;3@2 zLa5+ex76HZ`mVgLeY+!2H5h}2M##PYg{&#IR;AlRBmP;Ns3PfmBx(cW;@?)*;>ScQik(eTOZ{}2RvX_?IjAteKa~d zn%ek{^yNtO3Xha(z$dM|Jf_ zGBTiT>bbo?AH?u5Xm`dkp)@!oS*k<$!x+G&*FlFj*Ou%L@^S4YXyAp^45<^6qW6u1XHgM91g-URu{##0f+8d2aiwzyQ74s2^x>1P`X>c_UK z-bE>pkqn0ws+kx%HL$a(OLP`L^)OF0@n!-*UJd4fa=WF93>0Ya5ddfzNolIG9oYh862|whthE~Y zp@iM92Og9>x)tEiu2-@#bh( z;+_K4vvONUHODf&$CRk5GJz(M)YOs(e1OU{>;BpacvK7czbEM<9cwu%i|gD3KSmGa z1Y44>=T1`E?}@Ro*EXj@OV-frbDtOm#tbknay@xVmtB$rODgn!Yxf5qeUHuF?0hW` z8s>hL{kkWs380SHxUyHV{Pj`xF*OJ6ZglOe=a_Q%HBjYqkx+-gVDq_~3rp-Ap$mEv zj7K6*Vwr?k!-Symy2=%aC9E((&b!lIr+Y$7_d38?W_x1xf+b*pg0(FZ52Nc{_UrgD z?vI>VSk0IuOaAPP!N9=T)?s;RPe^Z2lcnS#v$HOaUKmXkoC5Q_pa%PnC`dArki|@! zq>Y&C6>b}acbvL$Dj<0IARu^t?(b)&Y(p*MVJZP5aBo}Uowc=fx4$Vu){$t9{v09j zMghB|u%b*m0&7#I47$Eb9cLyncw(b3X<`gVDJ)$;e(oV?B*-d*o9%zW6jUw&HzEQg zEapFNO9tWf6SLjzNZHOs^$oiFG6wF9+2lfIB#vj%2!4@;mA^zlfFq4>EseV4kcjjf zNMNxdwJ~ymcjQs)_*Dh?J`LuqwNkkWU>}S z$gU8GwW~syXq!-!G<(TtOEFUPOq&JJQUxldDq0s_f!s##B zg?N`JOVIv6r)Y9IdE?vT;OV{Sz6!a#|GSD9u!h_VqjS@(R%LAOjvr?f>D!qfRCI zGHh?%_0ewqFXJBv?e37wx9ELdF=+7!#;h}_`*^4A)2H#q%Cp=2;Ip=w |3tw^zH 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 z�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 J-P3vg{{V|wMWFxy literal 141773 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%0ALv#igQ8NZ|3?qHU^qD?G%J=d~i5NG+tY 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

pY19!`Gaxytl%FiSo0r1}x?B$#Xwa2HWdQ5vi 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 diff --git a/filterer/etc/filterer.urm.puml b/filterer/etc/filterer.urm.puml index 24060b6aa..c0bb0b54d 100644 --- a/filterer/etc/filterer.urm.puml +++ b/filterer/etc/filterer.urm.puml @@ -4,129 +4,93 @@ package com.iluwatar.filterer.domain { + by(Predicate) : G {abstract} } } -package com.iluwatar.filterer.issue { - interface Issue { - + endOffset() : int {abstract} - + startOffset() : int {abstract} - + type() : IssueType {abstract} +package com.iluwatar.filterer { + class App { + - LOGGER : Logger {static} + + App() + - filteringSimpleProbableThreats() {static} + - filteringSimpleThreats() {static} + + main(args : String[]) {static} } - interface IssueAwareText { - + filtered() : Filterer {abstract} - + issues() : List {abstract} - + text() : String {abstract} +} +package com.iluwatar.filterer.threat { + interface ProbabilisticThreatAwareSystem { + + filtered() : Filterer {abstract} + + threats() : List {abstract} } - class IssuePosition { - - endOffset : int - - startOffset : int - - IssuePosition(startOffset : int, endOffset : int) - ~ endOffset() : int - + equals(o : Object) : boolean - + hashCode() : int - + of(startOffset : int, endOffset : int) : IssuePosition {static} - ~ startOffset() : int - } - ~enum IssueType { - + GRAMMAR {static} - + SPELLING {static} - + valueOf(name : String) : IssueType {static} - + values() : IssueType[] {static} - } - interface IssueWiseText { - + filtered() : Filterer {abstract} - + issues() : List {abstract} - + text() : String {abstract} - } - interface ProbabilisticIssueAwareText { - + filtered() : Filterer {abstract} - + issues() : List {abstract} - } - interface ProbabilisticIssueWiseText { - + filtered() : Filterer {abstract} - + issues() : List {abstract} - } - interface ProbableIssue { + interface ProbableThreat { + probability() : double {abstract} } - class SimpleIssue { - - issuePosition : IssuePosition - - issueType : IssueType - ~ SimpleIssue(issuePosition : IssuePosition, issueType : IssueType) - + endOffset() : int + class SimpleProbabilisticThreatAwareSystem { + - systemId : String + - threats : ImmutableList + + SimpleProbabilisticThreatAwareSystem(systemId : String, threats : List) + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : ProbabilisticThreatAwareSystem + - filteredItems(predicate : Predicate) : List + hashCode() : int - + startOffset() : int - + type() : IssueType + + systemId() : String + + threats() : List + + toString() : String } - class SimpleIssueAwareText { - - issues : ImmutableList - - text : String - ~ SimpleIssueAwareText(text : String, issues : List) - + equals(o : Object) : boolean - + filtered() : Filterer - - filteredGroup(predicate : Predicate) : IssueAwareText - - filteredItems(predicate : Predicate) : ImmutableList - + hashCode() : int - + issues() : List - + text() : String - } - class SimpleIssueWiseText { - - issues : ImmutableList - - text : String - + SimpleIssueWiseText(text : String, issues : List) - + equals(o : Object) : boolean - + filtered() : Filterer - - filteredGroup(predicate : Predicate) : IssueWiseText - - filteredItems(predicate : Predicate) : ImmutableList - + hashCode() : int - + issues() : List - + text() : String - } - class SimpleProbabilisticIssueAwareText { - - issues : ImmutableList - - text : String - ~ SimpleProbabilisticIssueAwareText(text : String, issues : List) - + equals(o : Object) : boolean - + filtered() : Filterer - - filteredGroup(predicate : Predicate) : ProbabilisticIssueAwareText - - filteredItems(predicate : Predicate) : ImmutableList - + hashCode() : int - + issues() : List - + text() : String - } - class SimpleProbabilisticIssueWiseText { - - issues : ImmutableList - - text : String - + SimpleProbabilisticIssueWiseText(text : String, issues : List) - + equals(o : Object) : boolean - + filtered() : Filterer - - filteredGroup(predicate : Predicate) : ProbabilisticIssueWiseText - - filteredItems(predicate : Predicate) : ImmutableList - + hashCode() : int - + issues() : List - + text() : String - } - class SimpleProbableIssue { + class SimpleProbableThreat { - probability : double - ~ SimpleProbableIssue(issuePosition : IssuePosition, issueType : IssueType, probability : double) + + SimpleProbableThreat(name : String, id : int, threatType : ThreatType, probability : double) + equals(o : Object) : boolean + hashCode() : int + probability() : double + + toString() : String + } + class SimpleThreat { + - id : int + - name : String + - threatType : ThreatType + + SimpleThreat(threatType : ThreatType, id : int, name : String) + + id() : int + + name() : String + + toString() : String + + type() : ThreatType + } + class SimpleThreatAwareSystem { + - issues : ImmutableList + - systemId : String + + SimpleThreatAwareSystem(systemId : String, issues : List) + + equals(o : Object) : boolean + + filtered() : Filterer + - filteredGroup(predicate : Predicate) : ThreatAwareSystem + - filteredItems(predicate : Predicate) : List + + hashCode() : int + + systemId() : String + + threats() : List + + toString() : String + } + interface Threat { + + id() : int {abstract} + + name() : String {abstract} + + type() : ThreatType {abstract} + } + interface ThreatAwareSystem { + + filtered() : Filterer {abstract} + + systemId() : String {abstract} + + threats() : List {abstract} + } + enum ThreatType { + + ROOTKIT {static} + + TROJAN {static} + + WORM {static} + + valueOf(name : String) : ThreatType {static} + + values() : ThreatType[] {static} } } -SimpleIssueWiseText --> "-issues" Issue -SimpleProbabilisticIssueAwareText --> "-issues" ProbableIssue -SimpleIssue --> "-issueType" IssueType -SimpleIssueAwareText --> "-issues" Issue -SimpleProbabilisticIssueWiseText --> "-issues" ProbableIssue -SimpleIssue --> "-issuePosition" IssuePosition -ProbabilisticIssueAwareText --|> IssueAwareText -ProbabilisticIssueWiseText --|> IssueWiseText -ProbableIssue --|> Issue -SimpleIssue ..|> Issue -SimpleIssueAwareText ..|> IssueAwareText -SimpleIssueWiseText ..|> IssueWiseText -SimpleProbabilisticIssueAwareText ..|> ProbabilisticIssueAwareText -SimpleProbabilisticIssueWiseText ..|> ProbabilisticIssueWiseText -SimpleProbableIssue ..|> ProbableIssue -SimpleProbableIssue --|> SimpleIssue +SimpleThreatAwareSystem --> "-issues" Threat +SimpleThreat --> "-threatType" ThreatType +SimpleProbabilisticThreatAwareSystem --> "-threats" ProbableThreat +ProbabilisticThreatAwareSystem --|> ThreatAwareSystem +ProbableThreat --|> Threat +SimpleProbabilisticThreatAwareSystem ..|> ProbabilisticThreatAwareSystem +SimpleProbableThreat ..|> ProbableThreat +SimpleProbableThreat --|> SimpleThreat +SimpleThreat ..|> Threat +SimpleThreatAwareSystem ..|> ThreatAwareSystem @enduml \ No newline at end of file diff --git a/filterer/pom.xml b/filterer/pom.xml index 24dae571e..4477332ae 100644 --- a/filterer/pom.xml +++ b/filterer/pom.xml @@ -39,37 +39,34 @@ com.google.guava guava - 29.0-jre org.junit.jupiter junit-jupiter-api - 5.6.2 test org.junit.jupiter junit-jupiter-engine - 5.6.2 - test - - - org.assertj - assertj-core - 3.16.1 test - - maven-surefire-plugin - 2.22.2 - - - maven-failsafe-plugin - 2.22.2 + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.filterer.App + + + + + diff --git a/filterer/src/main/java/com/iluwatar/filterer/App.java b/filterer/src/main/java/com/iluwatar/filterer/App.java new file mode 100644 index 000000000..97ed24837 --- /dev/null +++ b/filterer/src/main/java/com/iluwatar/filterer/App.java @@ -0,0 +1,111 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer; + +import com.iluwatar.filterer.threat.ProbabilisticThreatAwareSystem; +import com.iluwatar.filterer.threat.ProbableThreat; +import com.iluwatar.filterer.threat.SimpleProbabilisticThreatAwareSystem; +import com.iluwatar.filterer.threat.SimpleProbableThreat; +import com.iluwatar.filterer.threat.SimpleThreat; +import com.iluwatar.filterer.threat.SimpleThreatAwareSystem; +import com.iluwatar.filterer.threat.Threat; +import com.iluwatar.filterer.threat.ThreatAwareSystem; +import com.iluwatar.filterer.threat.ThreatType; + +import java.util.List; +import java.util.function.Predicate; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This demo class represent how {@link com.iluwatar.filterer.domain.Filterer} pattern is used to + * filter container-like objects to return filtered versions of themselves. The container like + * objects are systems that are aware of threats that they can be vulnerable to. We would like + * to have a way to create copy of different system objects but with filtered threats. + * The thing is to keep it simple if we add new subtype of {@link Threat} + * (for example {@link ProbableThreat}) - we still need to be able to filter by it's properties. + */ +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) { + filteringSimpleThreats(); + filteringSimpleProbableThreats(); + } + + /** + * Demonstrates how to filter {@link com.iluwatar.filterer.threat.ProbabilisticThreatAwareSystem} + * based on probability property. The @{@link com.iluwatar.filterer.domain.Filterer#by(Predicate)} + * method is able to use {@link com.iluwatar.filterer.threat.ProbableThreat} + * as predicate argument. + */ + private static void filteringSimpleProbableThreats() { + LOGGER.info(" ### Filtering ProbabilisticThreatAwareSystem by probability ###"); + + ProbableThreat trojanArcBomb = + new SimpleProbableThreat("Trojan-ArcBomb", 1, ThreatType.TROJAN, 0.99); + ProbableThreat rootkit = + new SimpleProbableThreat("Rootkit-Kernel", 2, ThreatType.ROOTKIT, 0.8); + + List probableThreats = List.of(trojanArcBomb, rootkit); + + ProbabilisticThreatAwareSystem probabilisticThreatAwareSystem = + new SimpleProbabilisticThreatAwareSystem("System-1", probableThreats); + + LOGGER.info("Filtering ProbabilisticThreatAwareSystem. Initial : " + + probabilisticThreatAwareSystem); + + //Filtering using filterer + ProbabilisticThreatAwareSystem filtered = probabilisticThreatAwareSystem.filtered() + .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); + + LOGGER.info("Filtered by probability = 0.99 : " + filtered); + } + + /** + * Demonstrates how to filter {@link ThreatAwareSystem} based on startingOffset property + * of {@link SimpleThreat}. The @{@link com.iluwatar.filterer.domain.Filterer#by(Predicate)} + * method is able to use {@link Threat} as predicate argument. + */ + private static void filteringSimpleThreats() { + LOGGER.info("### Filtering ThreatAwareSystem by ThreatType ###"); + + Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); + Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); + List threats = List.of(rootkit, trojan); + + ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); + + LOGGER.info("Filtering ThreatAwareSystem. Initial : " + threatAwareSystem); + + //Filtering using Filterer + ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() + .by(threat -> threat.type() == ThreatType.ROOTKIT); + + LOGGER.info("Filtered by threatType = ROOTKIT : " + rootkitThreatAwareSystem); + } + +} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java b/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java deleted file mode 100644 index a771c1a82..000000000 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/IssuePosition.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * The MIT License - * Copyright © 2014-2019 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.filterer.issue; - -import java.util.Objects; - -/** - * Represents position of an issue. Takes starting and ending offset of issue in given text. - */ -public final class IssuePosition { - - private final int startOffset; - private final int endOffset; - - /** - * Factory method for constructing `IssuePosition` instances. - * @param startOffset starting offset of where the issue begins. - * @param endOffset ending offset of where the issue ends. - * @return new IssuePosition instance. - */ - public static IssuePosition of(final int startOffset, final int endOffset) { - return new IssuePosition(startOffset, endOffset); - } - - private IssuePosition(int startOffset, int endOffset) { - this.startOffset = startOffset; - this.endOffset = endOffset; - } - - int startOffset() { - return startOffset; - } - - int endOffset() { - return endOffset; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IssuePosition that = (IssuePosition) o; - return startOffset == that.startOffset - && endOffset == that.endOffset; - } - - @Override - public int hashCode() { - return Objects.hash(startOffset, endOffset); - } -} diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/threat/ProbabilisticThreatAwareSystem.java similarity index 79% rename from filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/ProbabilisticThreatAwareSystem.java index da15bdd99..3a2959828 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbabilisticIssueAwareText.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/ProbabilisticThreatAwareSystem.java @@ -21,29 +21,29 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import com.iluwatar.filterer.domain.Filterer; import java.util.List; /** - * Represents text that is aware of it's issues with given probability of their occurrence. + * Represents system that is aware of it's threats with given probability of their occurrence. */ -public interface ProbabilisticIssueAwareText extends IssueAwareText { +public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem { /** * {@inheritDoc} * @return */ @Override - List issues(); + List threats(); /** * {@inheritDoc} * @return */ @Override - Filterer filtered(); + Filterer filtered(); } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java b/filterer/src/main/java/com/iluwatar/filterer/threat/ProbableThreat.java similarity index 81% rename from filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/ProbableThreat.java index ccb047fa4..11e61dbf6 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/ProbableIssue.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/ProbableThreat.java @@ -21,15 +21,15 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; /** - * Represents issue that is an issue with given probability. + * Represents threat that might be a threat with given probability. */ -public interface ProbableIssue extends Issue { +public interface ProbableThreat extends Threat { /** - * Returns probability of occurrence of given issue. - * @return probability of occurrence of given issue. + * Returns probability of occurrence of given threat. + * @return probability of occurrence of given threat. */ double probability(); } \ No newline at end of file diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java similarity index 54% rename from filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java index e1b4afc82..37fae6a74 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareText.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import com.google.common.collect.ImmutableList; import com.iluwatar.filterer.domain.Filterer; @@ -29,56 +29,60 @@ import com.iluwatar.filterer.domain.Filterer; import java.util.List; import java.util.Objects; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * {@inheritDoc} */ -public class SimpleProbabilisticIssueAwareText implements ProbabilisticIssueAwareText { +public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem { - private final String text; - private final ImmutableList issues; + private final String systemId; + private final ImmutableList threats; - SimpleProbabilisticIssueAwareText(final String text, final List issues) { - this.text = text; - this.issues = ImmutableList.copyOf(issues); + public SimpleProbabilisticThreatAwareSystem( + final String systemId, + final List threats + ) { + this.systemId = systemId; + this.threats = ImmutableList.copyOf(threats); } /** * {@inheritDoc} */ @Override - public String text() { - return text; + public String systemId() { + return systemId; } /** * {@inheritDoc} */ @Override - public List issues() { - return issues; + public List threats() { + return threats; } /** * {@inheritDoc} */ @Override - public Filterer filtered() { + public Filterer filtered() { return this::filteredGroup; } - private ProbabilisticIssueAwareText filteredGroup( - final Predicate predicate + private ProbabilisticThreatAwareSystem filteredGroup( + final Predicate predicate ) { - return new SimpleProbabilisticIssueAwareText(this.text, filteredItems(predicate)); + return new SimpleProbabilisticThreatAwareSystem(this.systemId, filteredItems(predicate)); } - private ImmutableList filteredItems( - final Predicate predicate + private List filteredItems( + final Predicate predicate ) { - return this.issues.stream() + return this.threats.stream() .filter(predicate) - .collect(ImmutableList.toImmutableList()); + .collect(Collectors.toList()); } @Override @@ -89,13 +93,21 @@ public class SimpleProbabilisticIssueAwareText implements ProbabilisticIssueAwar if (o == null || getClass() != o.getClass()) { return false; } - SimpleProbabilisticIssueAwareText that = (SimpleProbabilisticIssueAwareText) o; - return text.equals(that.text) - && issues.equals(that.issues); + SimpleProbabilisticThreatAwareSystem that = (SimpleProbabilisticThreatAwareSystem) o; + return systemId.equals(that.systemId) + && threats.equals(that.threats); } @Override public int hashCode() { - return Objects.hash(text, issues); + return Objects.hash(systemId, threats); + } + + @Override + public String toString() { + return "SimpleProbabilisticThreatAwareSystem{" + + "systemId='" + systemId + '\'' + + ", threats=" + threats + + '}'; } } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java similarity index 74% rename from filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java index 2b7672256..27efc740a 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleProbableIssue.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java @@ -21,22 +21,23 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import java.util.Objects; /** * {@inheritDoc} */ -public class SimpleProbableIssue extends SimpleIssue implements ProbableIssue { +public class SimpleProbableThreat extends SimpleThreat implements ProbableThreat { private final double probability; - SimpleProbableIssue(final IssuePosition issuePosition, - final IssueType issueType, - final double probability + public SimpleProbableThreat(final String name, + final int id, + final ThreatType threatType, + final double probability ) { - super(issuePosition, issueType); + super(threatType, id, name); this.probability = probability; } @@ -59,7 +60,7 @@ public class SimpleProbableIssue extends SimpleIssue implements ProbableIssue { if (!super.equals(o)) { return false; } - SimpleProbableIssue that = (SimpleProbableIssue) o; + SimpleProbableThreat that = (SimpleProbableThreat) o; return Double.compare(that.probability, probability) == 0; } @@ -67,4 +68,12 @@ public class SimpleProbableIssue extends SimpleIssue implements ProbableIssue { public int hashCode() { return Objects.hash(super.hashCode(), probability); } + + @Override + public String toString() { + return "SimpleProbableThreat{" + + "probability=" + probability + + "} " + + super.toString(); + } } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java similarity index 59% rename from filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java index fde5b8d8e..fe7f155d4 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssue.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java @@ -21,42 +21,54 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import java.util.Objects; -public class SimpleIssue implements Issue { +/** + * Represents a simple threat. + */ +public class SimpleThreat implements Threat { - private final IssuePosition issuePosition; - private final IssueType issueType; + private final ThreatType threatType; + private final int id; + private final String name; - SimpleIssue(final IssuePosition issuePosition, IssueType issueType) { - this.issuePosition = issuePosition; - this.issueType = issueType; + /** + * Constructor. + * + * @param threatType {@link ThreatType}. + * @param id threat id. + * @param name threat name. + */ + public SimpleThreat(final ThreatType threatType, final int id, String name) { + this.threatType = threatType; + this.id = id; + this.name = name; } /** * {@inheritDoc} */ @Override - public int startOffset() { - return issuePosition.startOffset(); + public String name() { + return name; } /** * {@inheritDoc} */ @Override - public int endOffset() { - return issuePosition.endOffset(); + public int id() { + return id; } /** * {@inheritDoc} */ @Override - public IssueType type() { - return issueType; + public ThreatType type() { + return threatType; } @Override @@ -67,13 +79,23 @@ public class SimpleIssue implements Issue { if (o == null || getClass() != o.getClass()) { return false; } - SimpleIssue that = (SimpleIssue) o; - return issuePosition.equals(that.issuePosition) - && issueType == that.issueType; + SimpleThreat that = (SimpleThreat) o; + return id == that.id + && threatType == that.threatType + && Objects.equals(name, that.name); } @Override public int hashCode() { - return Objects.hash(issuePosition, issueType); + return Objects.hash(threatType, id, name); + } + + @Override + public String toString() { + return "SimpleThreat{" + + "threatType=" + threatType + + ", id=" + id + + ", name='" + name + '\'' + + '}'; } } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java similarity index 63% rename from filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java index c654a3aaa..49707cf50 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/SimpleIssueAwareText.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import com.google.common.collect.ImmutableList; import com.iluwatar.filterer.domain.Filterer; @@ -30,17 +30,18 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * {@inheritDoc} */ -public class SimpleIssueAwareText implements IssueAwareText { +public class SimpleThreatAwareSystem implements ThreatAwareSystem { - private final String text; - private final ImmutableList issues; + private final String systemId; + private final ImmutableList issues; - SimpleIssueAwareText(final String text, final List issues) { - this.text = text; + public SimpleThreatAwareSystem(final String systemId, final List issues) { + this.systemId = systemId; this.issues = ImmutableList.copyOf(issues); } @@ -48,15 +49,15 @@ public class SimpleIssueAwareText implements IssueAwareText { * {@inheritDoc} */ @Override - public String text() { - return text; + public String systemId() { + return systemId; } /** * {@inheritDoc} */ @Override - public List issues() { + public List threats() { return new ArrayList<>(issues); } @@ -64,18 +65,18 @@ public class SimpleIssueAwareText implements IssueAwareText { * {@inheritDoc} */ @Override - public Filterer filtered() { + public Filterer filtered() { return this::filteredGroup; } - private IssueAwareText filteredGroup(Predicate predicate) { - return new SimpleIssueAwareText(this.text, filteredItems(predicate)); + private ThreatAwareSystem filteredGroup(Predicate predicate) { + return new SimpleThreatAwareSystem(this.systemId, filteredItems(predicate)); } - private ImmutableList filteredItems(Predicate predicate) { + private List filteredItems(Predicate predicate) { return this.issues.stream() .filter(predicate) - .collect(ImmutableList.toImmutableList()); + .collect(Collectors.toList()); } @Override @@ -86,13 +87,21 @@ public class SimpleIssueAwareText implements IssueAwareText { if (o == null || getClass() != o.getClass()) { return false; } - SimpleIssueAwareText that = (SimpleIssueAwareText) o; - return text.equals(that.text) + SimpleThreatAwareSystem that = (SimpleThreatAwareSystem) o; + return systemId.equals(that.systemId) && issues.equals(that.issues); } @Override public int hashCode() { - return Objects.hash(text, issues); + return Objects.hash(systemId, issues); + } + + @Override + public String toString() { + return "SimpleThreatAwareSystem{" + + "systemId='" + systemId + + '\'' + ", issues=" + issues + + '}'; } } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java b/filterer/src/main/java/com/iluwatar/filterer/threat/Threat.java similarity index 71% rename from filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/Threat.java index 957ade6e5..515b59332 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/Issue.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/Threat.java @@ -21,29 +21,29 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; /** - * Represents an issue that can be detected in given text. + * Represents a threat that can be detected in given system. */ -public interface Issue { +public interface Threat { /** - * Returns starting position where the issue begins. + * Returns name of the threat. * - * @return value representing starting position of the issue. + * @return value representing name of the threat. */ - int startOffset(); + String name(); /** - * Returns ending position where the issue ends. + * Returns unique id of the threat. * - * @return value representing ending position of the issue. + * @return value representing threat id. */ - int endOffset(); + int id(); /** - * Returns issue type. - * @return {@link IssueType} + * Returns threat type. + * @return {@link ThreatType} */ - IssueType type(); + ThreatType type(); } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java b/filterer/src/main/java/com/iluwatar/filterer/threat/ThreatAwareSystem.java similarity index 78% rename from filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/ThreatAwareSystem.java index 8141ae849..b889d537d 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueAwareText.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/ThreatAwareSystem.java @@ -21,35 +21,35 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import com.iluwatar.filterer.domain.Filterer; import java.util.List; /** - * Represents text that is aware of issues that are present in it. + * Represents system that is aware of threats that are present in it. */ -public interface IssueAwareText { +public interface ThreatAwareSystem { /** - * Returns the analyzed text. + * Returns the system id. * - * @return the analyzed text. + * @return system id. */ - String text(); + String systemId(); /** - * Returns list of issues for this text. - * @return list of issues for this text. + * Returns list of threats for this system. + * @return list of threats for this system. */ - List issues(); + List threats(); /** * Returns the instance of {@link Filterer} helper interface that allows to covariantly * specify lower bound for predicate that we want to filter by. * @return an instance of {@link Filterer} helper interface. */ - Filterer filtered(); + Filterer filtered(); } diff --git a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java b/filterer/src/main/java/com/iluwatar/filterer/threat/ThreatType.java similarity index 92% rename from filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java rename to filterer/src/main/java/com/iluwatar/filterer/threat/ThreatType.java index ee2c12ce5..5f9a152a8 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/issue/IssueType.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/ThreatType.java @@ -21,6 +21,6 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; -enum IssueType { GRAMMAR, SPELLING } +public enum ThreatType { TROJAN, WORM, ROOTKIT } diff --git a/filterer/src/test/java/com/iluwatar/filterer/AppTest.java b/filterer/src/test/java/com/iluwatar/filterer/AppTest.java new file mode 100644 index 000000000..551ebcc18 --- /dev/null +++ b/filterer/src/test/java/com/iluwatar/filterer/AppTest.java @@ -0,0 +1,33 @@ +/* + * The MIT License + * Copyright © 2014-2019 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.filterer; + +import org.junit.jupiter.api.Test; + +class AppTest { + @Test + void shouldLaunchApp() { + App.main(new String[]{}); + } +} \ No newline at end of file diff --git a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java similarity index 60% rename from filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java rename to filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java index 142415111..592fabe88 100644 --- a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleProbabilisticIssueAwareTextTest.java +++ b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java @@ -21,32 +21,31 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import org.junit.jupiter.api.Test; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; - -class SimpleProbabilisticIssueAwareTextTest { +import static org.junit.jupiter.api.Assertions.assertEquals; +class SimpleProbabilisticThreatAwareSystemTest { @Test void shouldFilterByProbability() { //given - ProbableIssue spellingIssue = new SimpleProbableIssue(IssuePosition.of(4, 5), IssueType.SPELLING, 100); - ProbableIssue grammarIssue = new SimpleProbableIssue(IssuePosition.of(8, 12), IssueType.GRAMMAR, 99); - List issues = List.of(spellingIssue, grammarIssue); + ProbableThreat trojan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99); + ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8); + List probableThreats = List.of(trojan, rootkit); - SimpleProbabilisticIssueAwareText simpleIssueWiseText = new SimpleProbabilisticIssueAwareText("I mihgt gone there", issues); + ProbabilisticThreatAwareSystem simpleProbabilisticThreatAwareSystem = + new SimpleProbabilisticThreatAwareSystem("System-1", probableThreats); //when - ProbabilisticIssueAwareText filtered = simpleIssueWiseText.filtered() - .by(issue1 -> Double.compare(issue1.probability(), 99) == 0); + ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered() + .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); //then - assertThat(filtered.issues()).hasSize(1); - assertThat(filtered.issues()).element(0).isEqualTo(grammarIssue); + assertEquals(filtered.threats().size(), 1); + assertEquals(filtered.threats().get(0), trojan); } - } \ No newline at end of file diff --git a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java similarity index 62% rename from filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java rename to filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java index 1278128ae..91fb62718 100644 --- a/filterer/src/test/java/com/iluwatar/filterer/issue/SimpleIssueAwareTextTest.java +++ b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java @@ -21,32 +21,30 @@ * THE SOFTWARE. */ -package com.iluwatar.filterer.issue; +package com.iluwatar.filterer.threat; import org.junit.jupiter.api.Test; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; - -class SimpleIssueAwareTextTest { +import static org.junit.jupiter.api.Assertions.*; +class SimpleThreatAwareSystemTest { @Test - void shouldFilterByStartOffset() { + void shouldFilterByThreatType() { //given - SimpleIssue spellingIssue = new SimpleIssue(IssuePosition.of(4, 5), IssueType.SPELLING); - SimpleIssue grammarIssue = new SimpleIssue(IssuePosition.of(8, 12), IssueType.GRAMMAR); - List issues = List.of(spellingIssue, grammarIssue); + Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); + Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); + List threats = List.of(rootkit, trojan); - SimpleIssueAwareText simpleIssueWiseText = new SimpleIssueAwareText("I mihgt gone there", issues); + ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); //when - IssueAwareText filtered = simpleIssueWiseText.filtered() - .by(issue1 -> issue1.startOffset() == 4); + ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() + .by(threat -> threat.type() == ThreatType.ROOTKIT); //then - assertThat(filtered.issues()).hasSize(1); - assertThat(filtered.issues()).element(0).isEqualTo(spellingIssue); + assertEquals(rootkitThreatAwareSystem.threats().size(), 1); + assertEquals(rootkitThreatAwareSystem.threats().get(0), rootkit); } - -} +} \ No newline at end of file From 3d9afbaeec872b6ee36f68c9e5738f543d8d5562 Mon Sep 17 00:00:00 2001 From: Michal Krzywanski Date: Sat, 22 Aug 2020 18:24:41 +0200 Subject: [PATCH 273/285] fixed typo in read me --- filterer/README.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/filterer/README.MD b/filterer/README.MD index 3281e9ecc..b8207af6f 100644 --- a/filterer/README.MD +++ b/filterer/README.MD @@ -190,7 +190,8 @@ It enables you to easily extend filtering ability of container-like objects as b * [Application of Filterer pattern in domain of text analysis](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) ## Known uses -One of the uses is present on the blog presented in this link. It presents how to use `Filterer` pattern to create text issue anaylyzer with support for test cases used for unit testing. +One of the uses is present on the blog presented in [this](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) link. +It presents how to use `Filterer` pattern to create text issue analyzer with support for test cases used for unit testing. ## Consequences Pros : From e65b65257ebaf80113ec08f2ff85c2b8a1c10bd4 Mon Sep 17 00:00:00 2001 From: Michal Krzywanski Date: Sun, 23 Aug 2020 11:00:15 +0200 Subject: [PATCH 274/285] fixing typos in readme file, introducing var local type inference where possible --- filterer/README.MD | 8 +++---- .../main/java/com/iluwatar/filterer/App.java | 23 ++++++++----------- .../SimpleProbabilisticThreatAwareSystem.java | 2 +- .../filterer/threat/SimpleProbableThreat.java | 2 +- .../filterer/threat/SimpleThreat.java | 2 +- .../threat/SimpleThreatAwareSystem.java | 2 +- ...pleProbabilisticThreatAwareSystemTest.java | 8 +++---- .../threat/SimpleThreatAwareSystemTest.java | 8 +++---- 8 files changed, 26 insertions(+), 29 deletions(-) diff --git a/filterer/README.MD b/filterer/README.MD index b8207af6f..0c03e21a9 100644 --- a/filterer/README.MD +++ b/filterer/README.MD @@ -14,7 +14,7 @@ tags: Filterer ## Intent -The intent of this design pattern is to to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves. +The intent of this design pattern is to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves. ## Explanation Real world example @@ -59,7 +59,7 @@ The container-like object (`ThreatAwareSystem` in our case) needs to have a meth ability to covariantly specify a lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the container-like objects. In our example we will be able to pass a predicate that takes `? extends Threat` object and return `? extends ThreatAwareSystem` -from `Filtered::by` method. A simple implementation of `ThreadAwareSystem` : +from `Filtered::by` method. A simple implementation of `ThreatAwareSystem` : ```java public class SimpleThreatAwareSystem implements ThreatAwareSystem { @@ -99,7 +99,7 @@ public class SimpleThreatAwareSystem implements ThreatAwareSystem { ``` the `filtered` method is overridden to filter the threats list by given predicate. -Now if we introduce new subtype of `Thread` interface that adds probability with which given thread can appear : +Now if we introduce a new subtype of `Threat` interface that adds probability with which given threat can appear : ```java public interface ProbableThreat extends Threat { double probability(); @@ -116,7 +116,7 @@ public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem { } ```` Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify different return covariant type -by specifing different generic types. Our interfaces are clean and not cluttered by default implementations. We +by specifying different generic types. Our interfaces are clean and not cluttered by default implementations. We we will be able to filter `ProbabilisticThreatAwareSystem` by `ProbableThreat` properties : ```java public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem { diff --git a/filterer/src/main/java/com/iluwatar/filterer/App.java b/filterer/src/main/java/com/iluwatar/filterer/App.java index 97ed24837..43de5a646 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/App.java +++ b/filterer/src/main/java/com/iluwatar/filterer/App.java @@ -23,7 +23,6 @@ package com.iluwatar.filterer; -import com.iluwatar.filterer.threat.ProbabilisticThreatAwareSystem; import com.iluwatar.filterer.threat.ProbableThreat; import com.iluwatar.filterer.threat.SimpleProbabilisticThreatAwareSystem; import com.iluwatar.filterer.threat.SimpleProbableThreat; @@ -65,24 +64,22 @@ public class App { private static void filteringSimpleProbableThreats() { LOGGER.info(" ### Filtering ProbabilisticThreatAwareSystem by probability ###"); - ProbableThreat trojanArcBomb = - new SimpleProbableThreat("Trojan-ArcBomb", 1, ThreatType.TROJAN, 0.99); - ProbableThreat rootkit = - new SimpleProbableThreat("Rootkit-Kernel", 2, ThreatType.ROOTKIT, 0.8); + var trojanArcBomb = new SimpleProbableThreat("Trojan-ArcBomb", 1, ThreatType.TROJAN, 0.99); + var rootkit = new SimpleProbableThreat("Rootkit-Kernel", 2, ThreatType.ROOTKIT, 0.8); List probableThreats = List.of(trojanArcBomb, rootkit); - ProbabilisticThreatAwareSystem probabilisticThreatAwareSystem = - new SimpleProbabilisticThreatAwareSystem("System-1", probableThreats); + var probabilisticThreatAwareSystem = + new SimpleProbabilisticThreatAwareSystem("Sys-1", probableThreats); LOGGER.info("Filtering ProbabilisticThreatAwareSystem. Initial : " + probabilisticThreatAwareSystem); //Filtering using filterer - ProbabilisticThreatAwareSystem filtered = probabilisticThreatAwareSystem.filtered() + var filteredThreatAwareSystem = probabilisticThreatAwareSystem.filtered() .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); - LOGGER.info("Filtered by probability = 0.99 : " + filtered); + LOGGER.info("Filtered by probability = 0.99 : " + filteredThreatAwareSystem); } /** @@ -93,16 +90,16 @@ public class App { private static void filteringSimpleThreats() { LOGGER.info("### Filtering ThreatAwareSystem by ThreatType ###"); - Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); - Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); + var rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); + var trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); List threats = List.of(rootkit, trojan); - ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); + var threatAwareSystem = new SimpleThreatAwareSystem("Sys-1", threats); LOGGER.info("Filtering ThreatAwareSystem. Initial : " + threatAwareSystem); //Filtering using Filterer - ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() + var rootkitThreatAwareSystem = threatAwareSystem.filtered() .by(threat -> threat.type() == ThreatType.ROOTKIT); LOGGER.info("Filtered by threatType = ROOTKIT : " + rootkitThreatAwareSystem); diff --git a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java index 37fae6a74..3991d975e 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystem.java @@ -93,7 +93,7 @@ public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreat if (o == null || getClass() != o.getClass()) { return false; } - SimpleProbabilisticThreatAwareSystem that = (SimpleProbabilisticThreatAwareSystem) o; + var that = (SimpleProbabilisticThreatAwareSystem) o; return systemId.equals(that.systemId) && threats.equals(that.threats); } diff --git a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java index 27efc740a..54da07873 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleProbableThreat.java @@ -60,7 +60,7 @@ public class SimpleProbableThreat extends SimpleThreat implements ProbableThreat if (!super.equals(o)) { return false; } - SimpleProbableThreat that = (SimpleProbableThreat) o; + var that = (SimpleProbableThreat) o; return Double.compare(that.probability, probability) == 0; } diff --git a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java index fe7f155d4..08a8b0e17 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreat.java @@ -79,7 +79,7 @@ public class SimpleThreat implements Threat { if (o == null || getClass() != o.getClass()) { return false; } - SimpleThreat that = (SimpleThreat) o; + var that = (SimpleThreat) o; return id == that.id && threatType == that.threatType && Objects.equals(name, that.name); diff --git a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java index 49707cf50..f1dec40ae 100644 --- a/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java +++ b/filterer/src/main/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystem.java @@ -87,7 +87,7 @@ public class SimpleThreatAwareSystem implements ThreatAwareSystem { if (o == null || getClass() != o.getClass()) { return false; } - SimpleThreatAwareSystem that = (SimpleThreatAwareSystem) o; + var that = (SimpleThreatAwareSystem) o; return systemId.equals(that.systemId) && issues.equals(that.issues); } diff --git a/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java index 592fabe88..2f14ca057 100644 --- a/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java +++ b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleProbabilisticThreatAwareSystemTest.java @@ -33,15 +33,15 @@ class SimpleProbabilisticThreatAwareSystemTest { @Test void shouldFilterByProbability() { //given - ProbableThreat trojan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99); - ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8); + var trojan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99); + var rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8); List probableThreats = List.of(trojan, rootkit); - ProbabilisticThreatAwareSystem simpleProbabilisticThreatAwareSystem = + var simpleProbabilisticThreatAwareSystem = new SimpleProbabilisticThreatAwareSystem("System-1", probableThreats); //when - ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered() + var filtered = simpleProbabilisticThreatAwareSystem.filtered() .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); //then diff --git a/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java index 91fb62718..ea918c9ec 100644 --- a/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java +++ b/filterer/src/test/java/com/iluwatar/filterer/threat/SimpleThreatAwareSystemTest.java @@ -33,14 +33,14 @@ class SimpleThreatAwareSystemTest { @Test void shouldFilterByThreatType() { //given - Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); - Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); + var rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); + var trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); List threats = List.of(rootkit, trojan); - ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); + var threatAwareSystem = new SimpleThreatAwareSystem("System-1", threats); //when - ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() + var rootkitThreatAwareSystem = threatAwareSystem.filtered() .by(threat -> threat.type() == ThreatType.ROOTKIT); //then From 7411ea86bf6c2ea375d238f98b9d5a1d504d7c71 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 23 Aug 2020 13:59:14 +0000 Subject: [PATCH 275/285] docs: update README.md [skip ci] --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b0e297f82..d186a560b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![All Contributors](https://img.shields.io/badge/all_contributors-127-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-128-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -259,6 +259,7 @@ This project is licensed under the terms of the MIT license.
Bethan Palmer

💻
Toxic Dreamz

💻
Edy Cu Tjong

📖 +
Michał Krzywański

💻 From c18282ad5d3cf69e024288571b14edca1777f3d3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 23 Aug 2020 13:59:15 +0000 Subject: [PATCH 276/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index b968e8c31..18a590cc5 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1158,6 +1158,15 @@ "contributions": [ "doc" ] + }, + { + "login": "mkrzywanski", + "name": "Michał Krzywański", + "avatar_url": "https://avatars0.githubusercontent.com/u/15279585?v=4", + "profile": "https://github.com/mkrzywanski", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From 0cba30784430fe001a6fe944494d9459b9b55b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 23 Aug 2020 17:06:37 +0300 Subject: [PATCH 277/285] Fix readme filename --- filterer/{README.MD => README.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename filterer/{README.MD => README.md} (98%) diff --git a/filterer/README.MD b/filterer/README.md similarity index 98% rename from filterer/README.MD rename to filterer/README.md index 0c03e21a9..9ac49d6f8 100644 --- a/filterer/README.MD +++ b/filterer/README.md @@ -1,4 +1,4 @@ ---- # this is so called 'Yaml Front Matter', read up on it here: http://jekyllrb.com/docs/frontmatter/ +--- layout: pattern title: Filterer folder: filterer From 015b4181145680e4b93f1fc54895aacb1238cdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 23 Aug 2020 18:03:29 +0300 Subject: [PATCH 278/285] Update README.md --- filterer/README.md | 97 +++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/filterer/README.md b/filterer/README.md index 9ac49d6f8..89dc87e84 100644 --- a/filterer/README.md +++ b/filterer/README.md @@ -11,27 +11,33 @@ tags: --- ## Name / classification + Filterer ## Intent -The intent of this design pattern is to introduce a functional interface that will add a functionality for container-like objects to easily return filtered versions of themselves. + +The intent of this design pattern is to introduce a functional interface that will add a +functionality for container-like objects to easily return filtered versions of themselves. ## Explanation + Real world example -> We are designing a threat(malware) detection system. We can have different types of threats and systems. We have a requirement that -> system should be aware of threats that are present in it. In the design we have to take into consideration that new Threat types can be -> added later. Also there is a requirement that a system can filter itself based on the threats that it possesses (system acts as container-like object for threats). -> +> We are designing a threat (malware) detection software which can analyze target systems for +> threats that are present in it. In the design we have to take into consideration that new +> Threat types can be added later. Additionally, there is a requirement that the threat detection +> system can filter the detected threats based on different criteria (the target system acts as +> container-like object for threats). In plain words -> We need to be able to filter different types of systems(container-like objects) based on properties of Threats that they contain. -> Adding new properties for Threats should be easy (we still need the ability to filter by those new properties). +> Filterer pattern is a design pattern that helps container-like objects return filtered versions +> of themselves. **Programmatic Example** -To model the threat detection example presented above we introduce `Threat` and `ThreatAwareSystem` interfaces. +To model the threat detection example presented above we introduce `Threat` and `ThreatAwareSystem` +interfaces. ```java public interface Threat { @@ -47,19 +53,26 @@ public interface ThreatAwareSystem { } ``` -Notice the `filtered` method that returns instance of `Filterer` interface which is defined as : + +Notice the `filtered` method that returns instance of `Filterer` interface which is defined as: + ```java @FunctionalInterface public interface Filterer { G by(Predicate predicate); } ``` -it is used to fulfill the requirement for system to be able to filter itself based on threat properties. -The container-like object (`ThreatAwareSystem` in our case) needs to have a method that returns an instance of `Filterer`. This helper interface gives -ability to covariantly specify a lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the container-like objects. -In our example we will be able to pass a predicate that takes `? extends Threat` object and return `? extends ThreatAwareSystem` -from `Filtered::by` method. A simple implementation of `ThreatAwareSystem` : +It is used to fulfill the requirement for system to be able to filter itself based on threat +properties. The container-like object (`ThreatAwareSystem` in our case) needs to have a method that +returns an instance of `Filterer`. This helper interface gives ability to covariantly specify a +lower bound of contravariant `Predicate` in the subinterfaces of interfaces representing the +container-like objects. + +In our example we will be able to pass a predicate that takes `? extends Threat` object and +return `? extends ThreatAwareSystem` from `Filtered::by` method. A simple implementation +of `ThreatAwareSystem`: + ```java public class SimpleThreatAwareSystem implements ThreatAwareSystem { @@ -97,15 +110,21 @@ public class SimpleThreatAwareSystem implements ThreatAwareSystem { } } ``` -the `filtered` method is overridden to filter the threats list by given predicate. -Now if we introduce a new subtype of `Threat` interface that adds probability with which given threat can appear : +The `filtered` method is overridden to filter the threats list by given predicate. + +Now if we introduce a new subtype of `Threat` interface that adds probability with which given +threat can appear: + ```java public interface ProbableThreat extends Threat { double probability(); } ``` -we can also introduce a new interface that represents a system that is aware of threats with their probabilities : + +We can also introduce a new interface that represents a system that is aware of threats with their +probabilities: + ````java public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem { @Override @@ -115,9 +134,12 @@ public interface ProbabilisticThreatAwareSystem extends ThreatAwareSystem { Filterer filtered(); } ```` -Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify different return covariant type -by specifying different generic types. Our interfaces are clean and not cluttered by default implementations. We -we will be able to filter `ProbabilisticThreatAwareSystem` by `ProbableThreat` properties : + +Notice how we override the `filtered` method in `ProbabilisticThreatAwareSystem` and specify +different return covariant type by specifying different generic types. Our interfaces are clean and +not cluttered by default implementations. We we will be able to filter +`ProbabilisticThreatAwareSystem` by `ProbableThreat` properties: + ```java public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreatAwareSystem { @@ -156,7 +178,8 @@ public class SimpleProbabilisticThreatAwareSystem implements ProbabilisticThreat } ``` -Now if we want filter `ThreatAwareSystem` by threat type we can do : +Now if we want filter `ThreatAwareSystem` by threat type we can do: + ```java Threat rootkit = new SimpleThreat(ThreatType.ROOTKIT, 1, "Simple-Rootkit"); Threat trojan = new SimpleThreat(ThreatType.TROJAN, 2, "Simple-Trojan"); @@ -167,7 +190,9 @@ ThreatAwareSystem threatAwareSystem = new SimpleThreatAwareSystem("System-1", th ThreatAwareSystem rootkitThreatAwareSystem = threatAwareSystem.filtered() .by(threat -> threat.type() == ThreatType.ROOTKIT); ``` -or if we want to filter `ProbabilisticThreatAwareSystem` : + +Or if we want to filter `ProbabilisticThreatAwareSystem`: + ```java ProbableThreat malwareTroyan = new SimpleProbableThreat("Troyan-ArcBomb", 1, ThreatType.TROJAN, 0.99); ProbableThreat rootkit = new SimpleProbableThreat("Rootkit-System", 2, ThreatType.ROOTKIT, 0.8); @@ -178,27 +203,37 @@ ProbabilisticThreatAwareSystem simpleProbabilisticThreatAwareSystem =new SimpleP ProbabilisticThreatAwareSystem filtered = simpleProbabilisticThreatAwareSystem.filtered() .by(probableThreat -> Double.compare(probableThreat.probability(), 0.99) == 0); ``` + ## Class diagram + ![Filterer](./etc/filterer.png "Filterer") ## Applicability -Pattern can be used when working with container-like objects that use subtyping, instead of parametrizing(generics) for extensible class structure. -It enables you to easily extend filtering ability of container-like objects as business requirements change. + +Pattern can be used when working with container-like objects that use subtyping, instead of +parametrizing (generics) for extensible class structure. It enables you to easily extend filtering +ability of container-like objects as business requirements change. ## Tutorials + * [Article about Filterer pattern posted on it's author's blog](https://blog.tlinkowski.pl/2018/filterer-pattern/) * [Application of Filterer pattern in domain of text analysis](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) ## Known uses -One of the uses is present on the blog presented in [this](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) link. -It presents how to use `Filterer` pattern to create text issue analyzer with support for test cases used for unit testing. + +One of the uses is present on the blog presented in +[this](https://www.javacodegeeks.com/2019/02/filterer-pattern-10-steps.html) link. It presents how +to use `Filterer` pattern to create text issue analyzer with support for test cases used for unit +testing. ## Consequences -Pros : - * you can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes. -Cons : - * covariant return types mixed with generics can be sometimes tricky +Pros: + * You can easily introduce new subtypes for container-like objects and subtypes for objects that are contained within them and still be able to filter easily be new properties of those new subtypes. + +Cons: + * Covariant return types mixed with generics can be sometimes tricky ## Credits -* Author of the pattern : [Tomasz Linkowski](https://tlinkowski.pl/) \ No newline at end of file + +* Author of the pattern : [Tomasz Linkowski](https://tlinkowski.pl/) From 6d83ceba285fb2a62119f6169d8041ec05c196c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 23 Aug 2020 18:53:57 +0300 Subject: [PATCH 279/285] Update README.md --- bridge/README.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/bridge/README.md b/bridge/README.md index 82c2f2735..12a6358f5 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -9,20 +9,26 @@ tags: --- ## Also known as + Handle/Body ## Intent + Decouple an abstraction from its implementation so that the two can vary independently. ## Explanation Real world example -> Consider you have a weapon with different enchantments and you are supposed to allow mixing different weapons with different enchantments. What would you do? Create multiple copies of each of the weapons for each of the enchantments or would you just create separate enchantment and set it for the weapon as needed? Bridge pattern allows you to do the second. +> Consider you have a weapon with different enchantments, and you are supposed to allow mixing +> different weapons with different enchantments. What would you do? Create multiple copies of each +> of the weapons for each of the enchantments or would you just create separate enchantment and set +> it for the weapon as needed? Bridge pattern allows you to do the second. In Plain Words -> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy. +> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed +> from a hierarchy to another object with a separate hierarchy. Wikipedia says @@ -30,7 +36,7 @@ Wikipedia says **Programmatic Example** -Translating our weapon example from above. Here we have the `Weapon` hierarchy +Translating our weapon example from above. Here we have the `Weapon` hierarchy: ```java public interface Weapon { @@ -105,7 +111,7 @@ public class Hammer implements Weapon { } ``` -And the separate enchantment hierarchy +Here's the separate enchantment hierarchy: ```java public interface Enchantment { @@ -151,7 +157,7 @@ public class SoulEatingEnchantment implements Enchantment { } ``` -And both the hierarchies in action +Here are both hierarchies in action: ```java var enchantedSword = new Sword(new SoulEatingEnchantment()); @@ -178,18 +184,21 @@ hammer.unwield(); ``` ## Class diagram + ![alt text](./etc/bridge.urm.png "Bridge class diagram") ## Applicability + Use the Bridge pattern when -* you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time. -* both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently -* changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled. -* you have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies -* you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation. +* You want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time. +* Both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently. +* Changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled. +* You have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies. +* You want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation. ## Tutorial + * [Bridge Pattern Tutorial](https://www.journaldev.com/1491/bridge-design-pattern-java) ## Credits From 3754c666045c1420d9bd118bc0f4ea8fee85a680 Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Mon, 24 Aug 2020 23:12:45 +0200 Subject: [PATCH 280/285] Replace System Rules with System Lambda System Lambda is more specific. It only wraps the part of the code that produces the output. --- pom.xml | 6 +-- subclass-sandbox/pom.xml | 2 +- .../subclasssandbox/GroundDiveTest.java | 38 +++++++++--------- .../subclasssandbox/SkyLaunchTest.java | 39 +++++++++---------- 4 files changed, 40 insertions(+), 45 deletions(-) diff --git a/pom.xml b/pom.xml index 1275ce115..3b7ad3568 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 2.3.1 2.3.2 1.3.2 - 1.19.0 + 1.1.0 2.0.0 3.5.0 @@ -338,8 +338,8 @@ com.github.stefanbirkner - system-rules - ${system-rules.version} + system-lambda + ${system-lambda.version} test diff --git a/subclass-sandbox/pom.xml b/subclass-sandbox/pom.xml index ac718291e..a912ada3f 100644 --- a/subclass-sandbox/pom.xml +++ b/subclass-sandbox/pom.xml @@ -42,7 +42,7 @@ com.github.stefanbirkner - system-rules + system-lambda org.junit.jupiter diff --git a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/GroundDiveTest.java b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/GroundDiveTest.java index 97e2ac67d..3b379946c 100644 --- a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/GroundDiveTest.java +++ b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/GroundDiveTest.java @@ -23,55 +23,48 @@ package com.iluwatar.subclasssandbox; +import com.github.stefanbirkner.systemlambda.Statement; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; -import org.junit.contrib.java.lang.system.SystemOutRule; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized; /** * GroundDive unit tests. */ public class GroundDiveTest { - @Rule - public SystemOutRule log = new SystemOutRule().enableLog(); - @Test - public void testMove() { - log.clearLog(); + public void testMove() throws Exception { var groundDive = new GroundDive(); groundDive.move(1.0, 1.0, 1.0); - var outputLog = getLogContent(log.getLog()); + var outputLog = getLogContent(() -> groundDive.move(1.0, 1.0, 1.0)); var expectedLog = "Move to ( 1.0, 1.0, 1.0 )"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testPlaySound() { - log.clearLog(); + public void testPlaySound() throws Exception { var groundDive = new GroundDive(); - groundDive.playSound("SOUND_NAME", 1); - var outputLog = getLogContent(log.getLog()); + var outputLog = getLogContent(() -> groundDive.playSound("SOUND_NAME", 1)); var expectedLog = "Play SOUND_NAME with volumn 1"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testSpawnParticles() { - log.clearLog(); + public void testSpawnParticles() throws Exception { var groundDive = new GroundDive(); - groundDive.spawnParticles("PARTICLE_TYPE", 100); - final var outputLog = getLogContent(log.getLog()); + final var outputLog = getLogContent( + () -> groundDive.spawnParticles("PARTICLE_TYPE", 100)); final var expectedLog = "Spawn 100 particle with type PARTICLE_TYPE"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testActivate() { - log.clearLog(); + public void testActivate() throws Exception { var groundDive = new GroundDive(); - groundDive.activate(); - var logs = log.getLog().split("\n"); + var logs = tapSystemOutNormalized(groundDive::activate) + .split("\n"); final var expectedSize = 3; final var log1 = logs[0].split("-")[1].trim() + " -" + logs[0].split("-")[2].trim(); final var expectedLog1 = "Move to ( 0.0, 0.0, -20.0 )"; @@ -85,6 +78,11 @@ public class GroundDiveTest { Assert.assertEquals(log3, expectedLog3); } + private String getLogContent(Statement statement) throws Exception { + var log = tapSystemOutNormalized(statement); + return getLogContent(log); + } + private String getLogContent(String log) { return log.split("-")[1].trim(); } diff --git a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/SkyLaunchTest.java b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/SkyLaunchTest.java index e192737f6..d285e6c7d 100644 --- a/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/SkyLaunchTest.java +++ b/subclass-sandbox/src/test/java/com/iluwatar/subclasssandbox/SkyLaunchTest.java @@ -23,55 +23,47 @@ package com.iluwatar.subclasssandbox; +import com.github.stefanbirkner.systemlambda.Statement; import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; -import org.junit.contrib.java.lang.system.SystemOutRule; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized; /** * SkyLaunch unit tests. */ public class SkyLaunchTest { - @Rule - public SystemOutRule log = new SystemOutRule().enableLog(); - @Test - public void testMove() { - log.clearLog(); + public void testMove() throws Exception { var skyLaunch = new SkyLaunch(); - skyLaunch.move(1.0, 1.0, 1.0); - var outputLog = getLogContent(log.getLog()); + var outputLog = getLogContent(() -> skyLaunch.move(1.0, 1.0, 1.0)); var expectedLog = "Move to ( 1.0, 1.0, 1.0 )"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testPlaySound() { - log.clearLog(); + public void testPlaySound() throws Exception { var skyLaunch = new SkyLaunch(); - skyLaunch.playSound("SOUND_NAME", 1); - var outputLog = getLogContent(log.getLog()); + var outputLog = getLogContent(() -> skyLaunch.playSound("SOUND_NAME", 1)); var expectedLog = "Play SOUND_NAME with volumn 1"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testSpawnParticles() { - log.clearLog(); + public void testSpawnParticles() throws Exception { var skyLaunch = new SkyLaunch(); - skyLaunch.spawnParticles("PARTICLE_TYPE", 100); - var outputLog = getLogContent(log.getLog()); + var outputLog = getLogContent( + () -> skyLaunch.spawnParticles("PARTICLE_TYPE", 100)); var expectedLog = "Spawn 100 particle with type PARTICLE_TYPE"; Assert.assertEquals(outputLog, expectedLog); } @Test - public void testActivate() { - log.clearLog(); + public void testActivate() throws Exception { var skyLaunch = new SkyLaunch(); - skyLaunch.activate(); - var logs = log.getLog().split("\n"); + var logs = tapSystemOutNormalized(skyLaunch::activate) + .split("\n"); final var expectedSize = 3; final var log1 = getLogContent(logs[0]); final var expectedLog1 = "Move to ( 0.0, 0.0, 20.0 )"; @@ -85,6 +77,11 @@ public class SkyLaunchTest { Assert.assertEquals(log3, expectedLog3); } + private String getLogContent(Statement statement) throws Exception { + var log = tapSystemOutNormalized(statement); + return getLogContent(log); + } + private String getLogContent(String log) { return log.split("-")[1].trim(); } From b8f83c326dceb92290b31480a074c92058760989 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2020 14:42:53 +0000 Subject: [PATCH 281/285] docs: update README.md [skip ci] --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d186a560b..95fe7a912 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![All Contributors](https://img.shields.io/badge/all_contributors-128-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-129-orange.svg?style=flat-square)](#contributors-) # Introduction @@ -261,6 +261,9 @@ This project is licensed under the terms of the MIT license.
Edy Cu Tjong

📖
Michał Krzywański

💻 + +
Stefan Birkner

💻 + From 96aa21d0e886a9858637f30c0110aedf5f752c2d Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2020 14:42:54 +0000 Subject: [PATCH 282/285] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 18a590cc5..65eb0bf92 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1167,6 +1167,15 @@ "contributions": [ "code" ] + }, + { + "login": "stefanbirkner", + "name": "Stefan Birkner", + "avatar_url": "https://avatars1.githubusercontent.com/u/711349?v=4", + "profile": "https://www.stefan-birkner.de", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 4, From a0e5d061cbb55d4eb0cca1798e545ccbbb391de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 25 Aug 2020 21:20:30 +0300 Subject: [PATCH 283/285] Milestone 1.23.0 --- abstract-document/pom.xml | 2 +- abstract-factory/pom.xml | 2 +- acyclic-visitor/pom.xml | 2 +- adapter/pom.xml | 2 +- aggregator-microservices/aggregator-service/pom.xml | 2 +- aggregator-microservices/information-microservice/pom.xml | 2 +- aggregator-microservices/inventory-microservice/pom.xml | 2 +- aggregator-microservices/pom.xml | 2 +- ambassador/pom.xml | 2 +- api-gateway/api-gateway-service/pom.xml | 2 +- api-gateway/image-microservice/pom.xml | 2 +- api-gateway/pom.xml | 2 +- api-gateway/price-microservice/pom.xml | 2 +- arrange-act-assert/pom.xml | 2 +- async-method-invocation/pom.xml | 2 +- balking/pom.xml | 2 +- bridge/pom.xml | 2 +- builder/pom.xml | 2 +- business-delegate/pom.xml | 2 +- bytecode/pom.xml | 2 +- caching/pom.xml | 2 +- callback/pom.xml | 2 +- chain/pom.xml | 2 +- circuit-breaker/pom.xml | 2 +- collection-pipeline/pom.xml | 2 +- combinator/pom.xml | 2 +- command/pom.xml | 2 +- commander/pom.xml | 2 +- composite/pom.xml | 2 +- converter/pom.xml | 2 +- cqrs/pom.xml | 2 +- dao/pom.xml | 2 +- data-bus/pom.xml | 2 +- data-locality/pom.xml | 2 +- data-mapper/pom.xml | 2 +- data-transfer-object/pom.xml | 2 +- decorator/pom.xml | 2 +- delegation/pom.xml | 2 +- dependency-injection/pom.xml | 2 +- dirty-flag/pom.xml | 4 ++-- double-buffer/pom.xml | 2 +- double-checked-locking/pom.xml | 2 +- double-dispatch/pom.xml | 2 +- eip-aggregator/pom.xml | 2 +- eip-message-channel/pom.xml | 2 +- eip-publish-subscribe/pom.xml | 2 +- eip-splitter/pom.xml | 2 +- eip-wire-tap/pom.xml | 2 +- event-aggregator/pom.xml | 2 +- event-asynchronous/pom.xml | 2 +- event-driven-architecture/pom.xml | 2 +- event-queue/pom.xml | 2 +- event-sourcing/pom.xml | 2 +- execute-around/pom.xml | 2 +- extension-objects/pom.xml | 2 +- facade/pom.xml | 2 +- factory-kit/pom.xml | 2 +- factory-method/pom.xml | 2 +- feature-toggle/pom.xml | 2 +- filterer/pom.xml | 2 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/pom.xml | 2 +- game-loop/pom.xml | 2 +- guarded-suspension/pom.xml | 2 +- half-sync-half-async/pom.xml | 2 +- hexagonal/pom.xml | 2 +- intercepting-filter/pom.xml | 2 +- interpreter/pom.xml | 2 +- iterator/pom.xml | 2 +- layers/pom.xml | 2 +- lazy-loading/pom.xml | 2 +- leader-election/pom.xml | 2 +- leader-followers/pom.xml | 2 +- marker/pom.xml | 2 +- master-worker-pattern/pom.xml | 2 +- mediator/pom.xml | 2 +- memento/pom.xml | 2 +- model-view-controller/pom.xml | 2 +- model-view-presenter/pom.xml | 2 +- module/pom.xml | 2 +- monad/pom.xml | 2 +- monostate/pom.xml | 2 +- multiton/pom.xml | 2 +- mute-idiom/pom.xml | 2 +- mutex/pom.xml | 2 +- naked-objects/dom/pom.xml | 2 +- naked-objects/fixture/pom.xml | 2 +- naked-objects/integtests/pom.xml | 2 +- naked-objects/pom.xml | 8 ++++---- naked-objects/webapp/pom.xml | 2 +- null-object/pom.xml | 2 +- object-mother/pom.xml | 2 +- object-pool/pom.xml | 2 +- observer/pom.xml | 2 +- page-object/pom.xml | 2 +- page-object/sample-application/pom.xml | 2 +- page-object/test-automation/pom.xml | 2 +- partial-response/pom.xml | 2 +- pipeline/pom.xml | 2 +- poison-pill/pom.xml | 2 +- pom.xml | 2 +- priority-queue/pom.xml | 2 +- private-class-data/pom.xml | 2 +- producer-consumer/pom.xml | 2 +- promise/pom.xml | 2 +- property/pom.xml | 2 +- prototype/pom.xml | 2 +- proxy/pom.xml | 2 +- queue-load-leveling/pom.xml | 2 +- reactor/pom.xml | 2 +- reader-writer-lock/pom.xml | 2 +- repository/pom.xml | 2 +- resource-acquisition-is-initialization/pom.xml | 2 +- retry/pom.xml | 2 +- role-object/pom.xml | 2 +- saga/pom.xml | 2 +- semaphore/pom.xml | 2 +- servant/pom.xml | 2 +- serverless/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/pom.xml | 2 +- sharding/pom.xml | 2 +- singleton/pom.xml | 2 +- spatial-partition/pom.xml | 2 +- specification/pom.xml | 2 +- state/pom.xml | 2 +- step-builder/pom.xml | 2 +- strangler/pom.xml | 2 +- strategy/pom.xml | 2 +- subclass-sandbox/pom.xml | 2 +- template-method/pom.xml | 2 +- thread-pool/pom.xml | 2 +- throttling/pom.xml | 2 +- tls/pom.xml | 2 +- tolerant-reader/pom.xml | 2 +- trampoline/pom.xml | 2 +- transaction-script/pom.xml | 2 +- twin/pom.xml | 2 +- typeobjectpattern/pom.xml | 2 +- unit-of-work/pom.xml | 2 +- update-method/pom.xml | 2 +- value-object/pom.xml | 2 +- visitor/pom.xml | 2 +- 145 files changed, 149 insertions(+), 149 deletions(-) diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml index 5a19c3c81..a285e2d82 100644 --- a/abstract-document/pom.xml +++ b/abstract-document/pom.xml @@ -21,7 +21,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 abstract-document diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index 614b26232..4fe0b58cd 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 abstract-factory diff --git a/acyclic-visitor/pom.xml b/acyclic-visitor/pom.xml index 24bab933a..41a126d27 100644 --- a/acyclic-visitor/pom.xml +++ b/acyclic-visitor/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 acyclic-visitor diff --git a/adapter/pom.xml b/adapter/pom.xml index 4c725def8..2cd449c06 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 adapter diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml index f4482d0e3..8f1e2ad06 100644 --- a/aggregator-microservices/aggregator-service/pom.xml +++ b/aggregator-microservices/aggregator-service/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 aggregator-service diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml index f99d26b65..bde50bd98 100644 --- a/aggregator-microservices/information-microservice/pom.xml +++ b/aggregator-microservices/information-microservice/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml index f7899aa8f..76d506ed1 100644 --- a/aggregator-microservices/inventory-microservice/pom.xml +++ b/aggregator-microservices/inventory-microservice/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 inventory-microservice diff --git a/aggregator-microservices/pom.xml b/aggregator-microservices/pom.xml index a63ec2f12..e6bf655f7 100644 --- a/aggregator-microservices/pom.xml +++ b/aggregator-microservices/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 aggregator-microservices diff --git a/ambassador/pom.xml b/ambassador/pom.xml index 6d6a9894d..33f623457 100644 --- a/ambassador/pom.xml +++ b/ambassador/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 ambassador diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml index 744023e90..08c7d47dc 100644 --- a/api-gateway/api-gateway-service/pom.xml +++ b/api-gateway/api-gateway-service/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 api-gateway-service diff --git a/api-gateway/image-microservice/pom.xml b/api-gateway/image-microservice/pom.xml index 27ef343af..ba055bd71 100644 --- a/api-gateway/image-microservice/pom.xml +++ b/api-gateway/image-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 image-microservice diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml index 63a986996..0edcbc83a 100644 --- a/api-gateway/pom.xml +++ b/api-gateway/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 api-gateway diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml index e7b144c58..6b61ff2e5 100644 --- a/api-gateway/price-microservice/pom.xml +++ b/api-gateway/price-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/arrange-act-assert/pom.xml b/arrange-act-assert/pom.xml index bb0387e7a..c00660b01 100644 --- a/arrange-act-assert/pom.xml +++ b/arrange-act-assert/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 46aa9d354..32adc0508 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 async-method-invocation diff --git a/balking/pom.xml b/balking/pom.xml index 964531692..6d789244c 100644 --- a/balking/pom.xml +++ b/balking/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/bridge/pom.xml b/bridge/pom.xml index 0664bc9b5..ae50aba2e 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 bridge diff --git a/builder/pom.xml b/builder/pom.xml index dab9c66a7..069f6f841 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 builder diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index 26987c73a..9f7e3ea70 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 business-delegate diff --git a/bytecode/pom.xml b/bytecode/pom.xml index f6be69cee..cfae54ad1 100644 --- a/bytecode/pom.xml +++ b/bytecode/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/caching/pom.xml b/caching/pom.xml index 704dd78d0..82e7546f5 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 caching diff --git a/callback/pom.xml b/callback/pom.xml index c156527f5..a493c2cab 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 callback diff --git a/chain/pom.xml b/chain/pom.xml index cf70ad1e8..40966eebf 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 chain diff --git a/circuit-breaker/pom.xml b/circuit-breaker/pom.xml index fd9f85675..4df9aacd3 100644 --- a/circuit-breaker/pom.xml +++ b/circuit-breaker/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 circuit-breaker diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml index 6d8d467ad..e8de7ff33 100644 --- a/collection-pipeline/pom.xml +++ b/collection-pipeline/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 collection-pipeline diff --git a/combinator/pom.xml b/combinator/pom.xml index c2677fcc1..62c6a6658 100644 --- a/combinator/pom.xml +++ b/combinator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 combinator diff --git a/command/pom.xml b/command/pom.xml index 50a14c45f..557f2cd89 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 command diff --git a/commander/pom.xml b/commander/pom.xml index 7ab29e421..8b87442ae 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 commander diff --git a/composite/pom.xml b/composite/pom.xml index c16b95c13..5e41920d7 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 composite diff --git a/converter/pom.xml b/converter/pom.xml index 56eb2ccdb..b19db2bae 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 converter 4.0.0 diff --git a/cqrs/pom.xml b/cqrs/pom.xml index b3a0303e6..57570fff4 100644 --- a/cqrs/pom.xml +++ b/cqrs/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 cqrs diff --git a/dao/pom.xml b/dao/pom.xml index 7e8bd5625..ead5e030f 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 dao diff --git a/data-bus/pom.xml b/data-bus/pom.xml index e67135ae0..cc3553336 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -33,7 +33,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 data-bus diff --git a/data-locality/pom.xml b/data-locality/pom.xml index 660daa9b7..f14676b45 100644 --- a/data-locality/pom.xml +++ b/data-locality/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 data-locality diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml index 64f03a186..45221020b 100644 --- a/data-mapper/pom.xml +++ b/data-mapper/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 data-mapper diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index 459b1ab1e..d51b62d2c 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 data-transfer-object diff --git a/decorator/pom.xml b/decorator/pom.xml index c7e1a4d8d..1209d5efb 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 decorator diff --git a/delegation/pom.xml b/delegation/pom.xml index 63cd91842..8ff7c6617 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 9baffe382..85e8cdd1c 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 dependency-injection diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index 372a637f1..3908dca36 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -29,10 +29,10 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 dirty-flag - 1.23.0-SNAPSHOT + 1.23.0 dirty-flag http://maven.apache.org diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index cb66af1cb..e2e649fa9 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index a77546386..de8d27a4e 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 double-checked-locking diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 9582797a2..67febf5bb 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 double-dispatch diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml index 578d1bbf2..c77dded15 100644 --- a/eip-aggregator/pom.xml +++ b/eip-aggregator/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml index bea72b1f9..02db57903 100644 --- a/eip-message-channel/pom.xml +++ b/eip-message-channel/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 eip-message-channel diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml index e7b5462b6..ab98cf76a 100644 --- a/eip-publish-subscribe/pom.xml +++ b/eip-publish-subscribe/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 eip-publish-subscribe diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml index 9c06f3f8d..d1bc7f9c6 100644 --- a/eip-splitter/pom.xml +++ b/eip-splitter/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml index 06cbc33db..2b122a64e 100644 --- a/eip-wire-tap/pom.xml +++ b/eip-wire-tap/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index 5553de2e3..1f3896ff3 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 event-aggregator diff --git a/event-asynchronous/pom.xml b/event-asynchronous/pom.xml index 001b3b9a8..ccbda1f0a 100644 --- a/event-asynchronous/pom.xml +++ b/event-asynchronous/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 event-asynchronous diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index 17d2795c4..b9da44c6f 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 event-driven-architecture diff --git a/event-queue/pom.xml b/event-queue/pom.xml index fd8ce9902..1a93f9dad 100644 --- a/event-queue/pom.xml +++ b/event-queue/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 event-queue diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index 0d1592abb..486f6d9e0 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 event-sourcing diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 1752f04f5..65b98a10f 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 execute-around diff --git a/extension-objects/pom.xml b/extension-objects/pom.xml index 0194357ed..f6463e35f 100644 --- a/extension-objects/pom.xml +++ b/extension-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/facade/pom.xml b/facade/pom.xml index a7fdb88f0..3847f8cbb 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 facade diff --git a/factory-kit/pom.xml b/factory-kit/pom.xml index 87f27b341..521e6340f 100644 --- a/factory-kit/pom.xml +++ b/factory-kit/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 factory-kit diff --git a/factory-method/pom.xml b/factory-method/pom.xml index 5f0358d4d..8038a1ff9 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 factory-method diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 13f646b80..a44eae026 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/filterer/pom.xml b/filterer/pom.xml index 4477332ae..e64ac9846 100644 --- a/filterer/pom.xml +++ b/filterer/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 9eb063c13..28e573258 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/flux/pom.xml b/flux/pom.xml index 8effd0fc9..00435f835 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 flux diff --git a/flyweight/pom.xml b/flyweight/pom.xml index f3a8082b5..574f5b516 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 flyweight diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 34dabc182..447e341fd 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 front-controller diff --git a/game-loop/pom.xml b/game-loop/pom.xml index 706d3cff4..33a671449 100644 --- a/game-loop/pom.xml +++ b/game-loop/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/guarded-suspension/pom.xml b/guarded-suspension/pom.xml index 791c696c1..81cf96084 100644 --- a/guarded-suspension/pom.xml +++ b/guarded-suspension/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 jar guarded-suspension diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index fdb37edb0..e101a849c 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 half-sync-half-async diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml index 4873d0ddb..3a932749b 100644 --- a/hexagonal/pom.xml +++ b/hexagonal/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 hexagonal diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index ea8597374..59f82325a 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 intercepting-filter diff --git a/interpreter/pom.xml b/interpreter/pom.xml index 118cfcdf6..d2d538c24 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 interpreter diff --git a/iterator/pom.xml b/iterator/pom.xml index 514cedbea..1d4faf770 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 iterator diff --git a/layers/pom.xml b/layers/pom.xml index 2ebace18b..d4b218272 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 com.iluwatar.layers layers diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index a6a5d3a45..1bfe3b637 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 lazy-loading diff --git a/leader-election/pom.xml b/leader-election/pom.xml index 8fc833f18..b61041502 100644 --- a/leader-election/pom.xml +++ b/leader-election/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 leader-election diff --git a/leader-followers/pom.xml b/leader-followers/pom.xml index c0f27d051..2e5789acc 100644 --- a/leader-followers/pom.xml +++ b/leader-followers/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 leader-followers diff --git a/marker/pom.xml b/marker/pom.xml index 5212832d8..2e2ec74b5 100644 --- a/marker/pom.xml +++ b/marker/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index 26f4d70bb..54a72da69 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 master-worker-pattern diff --git a/mediator/pom.xml b/mediator/pom.xml index 23d28726b..ffae20778 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 mediator diff --git a/memento/pom.xml b/memento/pom.xml index 70121cea3..265825ccb 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 memento diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index a8ef230e8..6e2e062d8 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 model-view-controller diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index 97b47f82c..363dfd78c 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 model-view-presenter model-view-presenter diff --git a/module/pom.xml b/module/pom.xml index 5d9a6d529..4768ffcef 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 module diff --git a/monad/pom.xml b/monad/pom.xml index f553c3079..e74ee83eb 100644 --- a/monad/pom.xml +++ b/monad/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 monad diff --git a/monostate/pom.xml b/monostate/pom.xml index 0e51fc700..f00f7a677 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 monostate diff --git a/multiton/pom.xml b/multiton/pom.xml index ef1e9c892..8bb51845f 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 multiton diff --git a/mute-idiom/pom.xml b/mute-idiom/pom.xml index a32f6a3ea..0d24529fa 100644 --- a/mute-idiom/pom.xml +++ b/mute-idiom/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 mute-idiom diff --git a/mutex/pom.xml b/mutex/pom.xml index 9cdff25e4..c08862948 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 mutex diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index 0437c2da5..41cbd8571 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0-SNAPSHOT + 1.23.0 naked-objects-dom diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index 3457ac0a4..869af61f3 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0-SNAPSHOT + 1.23.0 naked-objects-fixture diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index f46541f48..f43b99197 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0-SNAPSHOT + 1.23.0 naked-objects-integtests diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index 5b7a2e0c7..0fc95946c 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 naked-objects pom @@ -333,17 +333,17 @@ ${project.groupId} naked-objects-dom - 1.23.0-SNAPSHOT + 1.23.0 ${project.groupId} naked-objects-fixture - 1.23.0-SNAPSHOT + 1.23.0 ${project.groupId} naked-objects-webapp - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index bbddeb791..86960a5fb 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0-SNAPSHOT + 1.23.0 naked-objects-webapp diff --git a/null-object/pom.xml b/null-object/pom.xml index 7b88fca79..e91b06f74 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 null-object diff --git a/object-mother/pom.xml b/object-mother/pom.xml index 5ac3ce410..07d724e76 100644 --- a/object-mother/pom.xml +++ b/object-mother/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 object-mother diff --git a/object-pool/pom.xml b/object-pool/pom.xml index 2adad8942..ed3f87a0d 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 object-pool diff --git a/observer/pom.xml b/observer/pom.xml index 1e48268d8..e971c5602 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 observer diff --git a/page-object/pom.xml b/page-object/pom.xml index 4bf31d72e..6c1066fce 100644 --- a/page-object/pom.xml +++ b/page-object/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 page-object pom diff --git a/page-object/sample-application/pom.xml b/page-object/sample-application/pom.xml index 5ded184cc..c715418d5 100644 --- a/page-object/sample-application/pom.xml +++ b/page-object/sample-application/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 sample-application diff --git a/page-object/test-automation/pom.xml b/page-object/test-automation/pom.xml index 68025f4b8..f2ca98689 100644 --- a/page-object/test-automation/pom.xml +++ b/page-object/test-automation/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 test-automation diff --git a/partial-response/pom.xml b/partial-response/pom.xml index d10a496dd..a4788e5d1 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/pipeline/pom.xml b/pipeline/pom.xml index 8c511cd8a..a29007cda 100644 --- a/pipeline/pom.xml +++ b/pipeline/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 pipeline diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index 4989581d7..38d12c6c7 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 poison-pill diff --git a/pom.xml b/pom.xml index 3b7ad3568..56c593574 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 pom 2014-2019 diff --git a/priority-queue/pom.xml b/priority-queue/pom.xml index 7f435f489..338079a66 100644 --- a/priority-queue/pom.xml +++ b/priority-queue/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index cb81ca3fc..bc4eeff65 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 private-class-data diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index ab1872c51..853eb68f8 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 producer-consumer diff --git a/promise/pom.xml b/promise/pom.xml index 4a9d76df1..ac0f66a43 100644 --- a/promise/pom.xml +++ b/promise/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 promise diff --git a/property/pom.xml b/property/pom.xml index d271af036..e96371c9c 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 property diff --git a/prototype/pom.xml b/prototype/pom.xml index e68b11892..7fc26080a 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 prototype diff --git a/proxy/pom.xml b/proxy/pom.xml index f54c77dcf..8d2749483 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 proxy diff --git a/queue-load-leveling/pom.xml b/queue-load-leveling/pom.xml index ee6e6c623..8f9a785c9 100644 --- a/queue-load-leveling/pom.xml +++ b/queue-load-leveling/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 queue-load-leveling diff --git a/reactor/pom.xml b/reactor/pom.xml index b95b0b6e2..424c00db7 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 reactor diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index 92f53df66..10d49f6cc 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 reader-writer-lock diff --git a/repository/pom.xml b/repository/pom.xml index 0b98cdb41..5511c4fc3 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 repository diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index ef8e19f48..80d34e3aa 100644 --- a/resource-acquisition-is-initialization/pom.xml +++ b/resource-acquisition-is-initialization/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 resource-acquisition-is-initialization diff --git a/retry/pom.xml b/retry/pom.xml index e6c2701e0..db59fa049 100644 --- a/retry/pom.xml +++ b/retry/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 retry jar diff --git a/role-object/pom.xml b/role-object/pom.xml index c980adc2c..2b3e07be0 100644 --- a/role-object/pom.xml +++ b/role-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 role-object diff --git a/saga/pom.xml b/saga/pom.xml index 1971ae6cf..c83c8fb45 100644 --- a/saga/pom.xml +++ b/saga/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 saga diff --git a/semaphore/pom.xml b/semaphore/pom.xml index b6375366b..0a2ac7aed 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 semaphore diff --git a/servant/pom.xml b/servant/pom.xml index 395060d50..e8925cea9 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 servant diff --git a/serverless/pom.xml b/serverless/pom.xml index 1fb55ec47..c9d7ec71b 100644 --- a/serverless/pom.xml +++ b/serverless/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 diff --git a/service-layer/pom.xml b/service-layer/pom.xml index 881ec8ba6..aaee48310 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 service-layer diff --git a/service-locator/pom.xml b/service-locator/pom.xml index 1d8e9fcd8..ed2366ed0 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 service-locator diff --git a/sharding/pom.xml b/sharding/pom.xml index 2d00629bc..61c15db5b 100644 --- a/sharding/pom.xml +++ b/sharding/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/singleton/pom.xml b/singleton/pom.xml index b09602d0e..7b7686108 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 singleton diff --git a/spatial-partition/pom.xml b/spatial-partition/pom.xml index 7312427d0..2f47d73d9 100644 --- a/spatial-partition/pom.xml +++ b/spatial-partition/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 spatial-partition diff --git a/specification/pom.xml b/specification/pom.xml index 9214e984e..d2945516b 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 specification diff --git a/state/pom.xml b/state/pom.xml index b1ff3f5f3..c53f3d797 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 state diff --git a/step-builder/pom.xml b/step-builder/pom.xml index 3cea3b158..1de9b653d 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 step-builder diff --git a/strangler/pom.xml b/strangler/pom.xml index 4a1fb42ba..ba85f7184 100644 --- a/strangler/pom.xml +++ b/strangler/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/strategy/pom.xml b/strategy/pom.xml index cd1395c7a..aad38f1ce 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 strategy diff --git a/subclass-sandbox/pom.xml b/subclass-sandbox/pom.xml index a912ada3f..144f099a3 100644 --- a/subclass-sandbox/pom.xml +++ b/subclass-sandbox/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/template-method/pom.xml b/template-method/pom.xml index c449ef04f..36a0d8550 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 template-method diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index 0ea0b1266..abcb8a9f5 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 thread-pool diff --git a/throttling/pom.xml b/throttling/pom.xml index 6ae062c5e..77f911c24 100644 --- a/throttling/pom.xml +++ b/throttling/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/tls/pom.xml b/tls/pom.xml index 7100ae295..f6adc911f 100644 --- a/tls/pom.xml +++ b/tls/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 tls diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index 2966cca19..3324f75f0 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 tolerant-reader diff --git a/trampoline/pom.xml b/trampoline/pom.xml index 13988ca92..c651b4f8b 100644 --- a/trampoline/pom.xml +++ b/trampoline/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 trampoline diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index 5dc2aa981..081567c47 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/twin/pom.xml b/twin/pom.xml index cb60511c9..37c06bd20 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 twin diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index c8f0005af..32e252aea 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 typeobjectpattern diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index 0f8f0b21a..730b7921b 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/update-method/pom.xml b/update-method/pom.xml index 78b89555a..2659d1e2c 100644 --- a/update-method/pom.xml +++ b/update-method/pom.xml @@ -28,7 +28,7 @@ java-design-patterns com.iluwatar - 1.23.0-SNAPSHOT + 1.23.0 4.0.0 diff --git a/value-object/pom.xml b/value-object/pom.xml index aa4101b5c..a2dd714de 100644 --- a/value-object/pom.xml +++ b/value-object/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 value-object diff --git a/visitor/pom.xml b/visitor/pom.xml index 00497b41f..dddb4d4e3 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0-SNAPSHOT + 1.23.0 visitor From 723afb85ba1ce9a1865040a8471ab457dc0edc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 25 Aug 2020 21:21:36 +0300 Subject: [PATCH 284/285] Set version for next development iteration --- abstract-document/pom.xml | 2 +- abstract-factory/pom.xml | 2 +- acyclic-visitor/pom.xml | 2 +- adapter/pom.xml | 2 +- aggregator-microservices/aggregator-service/pom.xml | 2 +- aggregator-microservices/information-microservice/pom.xml | 2 +- aggregator-microservices/inventory-microservice/pom.xml | 2 +- aggregator-microservices/pom.xml | 2 +- ambassador/pom.xml | 2 +- api-gateway/api-gateway-service/pom.xml | 2 +- api-gateway/image-microservice/pom.xml | 2 +- api-gateway/pom.xml | 2 +- api-gateway/price-microservice/pom.xml | 2 +- arrange-act-assert/pom.xml | 2 +- async-method-invocation/pom.xml | 2 +- balking/pom.xml | 2 +- bridge/pom.xml | 2 +- builder/pom.xml | 2 +- business-delegate/pom.xml | 2 +- bytecode/pom.xml | 2 +- caching/pom.xml | 2 +- callback/pom.xml | 2 +- chain/pom.xml | 2 +- circuit-breaker/pom.xml | 2 +- collection-pipeline/pom.xml | 2 +- combinator/pom.xml | 2 +- command/pom.xml | 2 +- commander/pom.xml | 2 +- composite/pom.xml | 2 +- converter/pom.xml | 2 +- cqrs/pom.xml | 2 +- dao/pom.xml | 2 +- data-bus/pom.xml | 2 +- data-locality/pom.xml | 2 +- data-mapper/pom.xml | 2 +- data-transfer-object/pom.xml | 2 +- decorator/pom.xml | 2 +- delegation/pom.xml | 2 +- dependency-injection/pom.xml | 2 +- dirty-flag/pom.xml | 4 ++-- double-buffer/pom.xml | 2 +- double-checked-locking/pom.xml | 2 +- double-dispatch/pom.xml | 2 +- eip-aggregator/pom.xml | 2 +- eip-message-channel/pom.xml | 2 +- eip-publish-subscribe/pom.xml | 2 +- eip-splitter/pom.xml | 2 +- eip-wire-tap/pom.xml | 2 +- event-aggregator/pom.xml | 2 +- event-asynchronous/pom.xml | 2 +- event-driven-architecture/pom.xml | 2 +- event-queue/pom.xml | 2 +- event-sourcing/pom.xml | 2 +- execute-around/pom.xml | 2 +- extension-objects/pom.xml | 2 +- facade/pom.xml | 2 +- factory-kit/pom.xml | 2 +- factory-method/pom.xml | 2 +- feature-toggle/pom.xml | 2 +- filterer/pom.xml | 2 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/pom.xml | 2 +- game-loop/pom.xml | 2 +- guarded-suspension/pom.xml | 2 +- half-sync-half-async/pom.xml | 2 +- hexagonal/pom.xml | 2 +- intercepting-filter/pom.xml | 2 +- interpreter/pom.xml | 2 +- iterator/pom.xml | 2 +- layers/pom.xml | 2 +- lazy-loading/pom.xml | 2 +- leader-election/pom.xml | 2 +- leader-followers/pom.xml | 2 +- marker/pom.xml | 2 +- master-worker-pattern/pom.xml | 2 +- mediator/pom.xml | 2 +- memento/pom.xml | 2 +- model-view-controller/pom.xml | 2 +- model-view-presenter/pom.xml | 2 +- module/pom.xml | 2 +- monad/pom.xml | 2 +- monostate/pom.xml | 2 +- multiton/pom.xml | 2 +- mute-idiom/pom.xml | 2 +- mutex/pom.xml | 2 +- naked-objects/dom/pom.xml | 2 +- naked-objects/fixture/pom.xml | 2 +- naked-objects/integtests/pom.xml | 2 +- naked-objects/pom.xml | 8 ++++---- naked-objects/webapp/pom.xml | 2 +- null-object/pom.xml | 2 +- object-mother/pom.xml | 2 +- object-pool/pom.xml | 2 +- observer/pom.xml | 2 +- page-object/pom.xml | 2 +- page-object/sample-application/pom.xml | 2 +- page-object/test-automation/pom.xml | 2 +- partial-response/pom.xml | 2 +- pipeline/pom.xml | 2 +- poison-pill/pom.xml | 2 +- pom.xml | 2 +- priority-queue/pom.xml | 2 +- private-class-data/pom.xml | 2 +- producer-consumer/pom.xml | 2 +- promise/pom.xml | 2 +- property/pom.xml | 2 +- prototype/pom.xml | 2 +- proxy/pom.xml | 2 +- queue-load-leveling/pom.xml | 2 +- reactor/pom.xml | 2 +- reader-writer-lock/pom.xml | 2 +- repository/pom.xml | 2 +- resource-acquisition-is-initialization/pom.xml | 2 +- retry/pom.xml | 2 +- role-object/pom.xml | 2 +- saga/pom.xml | 2 +- semaphore/pom.xml | 2 +- servant/pom.xml | 2 +- serverless/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/pom.xml | 2 +- sharding/pom.xml | 2 +- singleton/pom.xml | 2 +- spatial-partition/pom.xml | 2 +- specification/pom.xml | 2 +- state/pom.xml | 2 +- step-builder/pom.xml | 2 +- strangler/pom.xml | 2 +- strategy/pom.xml | 2 +- subclass-sandbox/pom.xml | 2 +- template-method/pom.xml | 2 +- thread-pool/pom.xml | 2 +- throttling/pom.xml | 2 +- tls/pom.xml | 2 +- tolerant-reader/pom.xml | 2 +- trampoline/pom.xml | 2 +- transaction-script/pom.xml | 2 +- twin/pom.xml | 2 +- typeobjectpattern/pom.xml | 2 +- unit-of-work/pom.xml | 2 +- update-method/pom.xml | 2 +- value-object/pom.xml | 2 +- visitor/pom.xml | 2 +- 145 files changed, 149 insertions(+), 149 deletions(-) diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml index a285e2d82..15e7cc54d 100644 --- a/abstract-document/pom.xml +++ b/abstract-document/pom.xml @@ -21,7 +21,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT abstract-document diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index 4fe0b58cd..2328c60a8 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT abstract-factory diff --git a/acyclic-visitor/pom.xml b/acyclic-visitor/pom.xml index 41a126d27..8c53b8750 100644 --- a/acyclic-visitor/pom.xml +++ b/acyclic-visitor/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT acyclic-visitor diff --git a/adapter/pom.xml b/adapter/pom.xml index 2cd449c06..a4d8d7b12 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT adapter diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml index 8f1e2ad06..b7c2bac66 100644 --- a/aggregator-microservices/aggregator-service/pom.xml +++ b/aggregator-microservices/aggregator-service/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 aggregator-service diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml index bde50bd98..71935757f 100644 --- a/aggregator-microservices/information-microservice/pom.xml +++ b/aggregator-microservices/information-microservice/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml index 76d506ed1..6c2726a35 100644 --- a/aggregator-microservices/inventory-microservice/pom.xml +++ b/aggregator-microservices/inventory-microservice/pom.xml @@ -20,7 +20,7 @@ aggregator-microservices com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 inventory-microservice diff --git a/aggregator-microservices/pom.xml b/aggregator-microservices/pom.xml index e6bf655f7..9e66e9be0 100644 --- a/aggregator-microservices/pom.xml +++ b/aggregator-microservices/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 aggregator-microservices diff --git a/ambassador/pom.xml b/ambassador/pom.xml index 33f623457..0e5e208d5 100644 --- a/ambassador/pom.xml +++ b/ambassador/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 ambassador diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml index 08c7d47dc..c5ca117b6 100644 --- a/api-gateway/api-gateway-service/pom.xml +++ b/api-gateway/api-gateway-service/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 api-gateway-service diff --git a/api-gateway/image-microservice/pom.xml b/api-gateway/image-microservice/pom.xml index ba055bd71..821857449 100644 --- a/api-gateway/image-microservice/pom.xml +++ b/api-gateway/image-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 image-microservice diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml index 0edcbc83a..8ed569412 100644 --- a/api-gateway/pom.xml +++ b/api-gateway/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 api-gateway diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml index 6b61ff2e5..dc3591bf3 100644 --- a/api-gateway/price-microservice/pom.xml +++ b/api-gateway/price-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/arrange-act-assert/pom.xml b/arrange-act-assert/pom.xml index c00660b01..4b0d57ebf 100644 --- a/arrange-act-assert/pom.xml +++ b/arrange-act-assert/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 32adc0508..b4f7dd670 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT async-method-invocation diff --git a/balking/pom.xml b/balking/pom.xml index 6d789244c..0a86bc430 100644 --- a/balking/pom.xml +++ b/balking/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/bridge/pom.xml b/bridge/pom.xml index ae50aba2e..41271814c 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT bridge diff --git a/builder/pom.xml b/builder/pom.xml index 069f6f841..6aa467f9e 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT builder diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index 9f7e3ea70..a46e856a9 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -22,7 +22,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT business-delegate diff --git a/bytecode/pom.xml b/bytecode/pom.xml index cfae54ad1..d21064be4 100644 --- a/bytecode/pom.xml +++ b/bytecode/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/caching/pom.xml b/caching/pom.xml index 82e7546f5..627f76e98 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT caching diff --git a/callback/pom.xml b/callback/pom.xml index a493c2cab..a74b653e1 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT callback diff --git a/chain/pom.xml b/chain/pom.xml index 40966eebf..9a7097e6d 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT chain diff --git a/circuit-breaker/pom.xml b/circuit-breaker/pom.xml index 4df9aacd3..083c527fa 100644 --- a/circuit-breaker/pom.xml +++ b/circuit-breaker/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT circuit-breaker diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml index e8de7ff33..08c41880b 100644 --- a/collection-pipeline/pom.xml +++ b/collection-pipeline/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT collection-pipeline diff --git a/combinator/pom.xml b/combinator/pom.xml index 62c6a6658..4886873cd 100644 --- a/combinator/pom.xml +++ b/combinator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT combinator diff --git a/command/pom.xml b/command/pom.xml index 557f2cd89..3869d4b44 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT command diff --git a/commander/pom.xml b/commander/pom.xml index 8b87442ae..baabc04fc 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT commander diff --git a/composite/pom.xml b/composite/pom.xml index 5e41920d7..6f7147482 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT composite diff --git a/converter/pom.xml b/converter/pom.xml index b19db2bae..1bed5e973 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -20,7 +20,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT converter 4.0.0 diff --git a/cqrs/pom.xml b/cqrs/pom.xml index 57570fff4..1838ed599 100644 --- a/cqrs/pom.xml +++ b/cqrs/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT cqrs diff --git a/dao/pom.xml b/dao/pom.xml index ead5e030f..32e9ef1ff 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT dao diff --git a/data-bus/pom.xml b/data-bus/pom.xml index cc3553336..4db738307 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -33,7 +33,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT data-bus diff --git a/data-locality/pom.xml b/data-locality/pom.xml index f14676b45..88fd96c64 100644 --- a/data-locality/pom.xml +++ b/data-locality/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT data-locality diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml index 45221020b..cf17de69b 100644 --- a/data-mapper/pom.xml +++ b/data-mapper/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT data-mapper diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index d51b62d2c..2529b3756 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT data-transfer-object diff --git a/decorator/pom.xml b/decorator/pom.xml index 1209d5efb..b075704c8 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT decorator diff --git a/delegation/pom.xml b/delegation/pom.xml index 8ff7c6617..d7ad81362 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 85e8cdd1c..f3aaba520 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT dependency-injection diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index 3908dca36..b796ab37a 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -29,10 +29,10 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT dirty-flag - 1.23.0 + 1.24.0-SNAPSHOT dirty-flag http://maven.apache.org diff --git a/double-buffer/pom.xml b/double-buffer/pom.xml index e2e649fa9..cc4032074 100644 --- a/double-buffer/pom.xml +++ b/double-buffer/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index de8d27a4e..04aba2260 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT double-checked-locking diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 67febf5bb..275b505a5 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT double-dispatch diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml index c77dded15..efee153a3 100644 --- a/eip-aggregator/pom.xml +++ b/eip-aggregator/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml index 02db57903..12fe153e3 100644 --- a/eip-message-channel/pom.xml +++ b/eip-message-channel/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT eip-message-channel diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml index ab98cf76a..f354b1ee3 100644 --- a/eip-publish-subscribe/pom.xml +++ b/eip-publish-subscribe/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT eip-publish-subscribe diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml index d1bc7f9c6..5b4758a9e 100644 --- a/eip-splitter/pom.xml +++ b/eip-splitter/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml index 2b122a64e..332861547 100644 --- a/eip-wire-tap/pom.xml +++ b/eip-wire-tap/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index 1f3896ff3..813521c48 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT event-aggregator diff --git a/event-asynchronous/pom.xml b/event-asynchronous/pom.xml index ccbda1f0a..06921a100 100644 --- a/event-asynchronous/pom.xml +++ b/event-asynchronous/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT event-asynchronous diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index b9da44c6f..c40a8821b 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT event-driven-architecture diff --git a/event-queue/pom.xml b/event-queue/pom.xml index 1a93f9dad..232b9abaa 100644 --- a/event-queue/pom.xml +++ b/event-queue/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT event-queue diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index 486f6d9e0..44af5fc5e 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT event-sourcing diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 65b98a10f..2d0640fe0 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT execute-around diff --git a/extension-objects/pom.xml b/extension-objects/pom.xml index f6463e35f..7247a9676 100644 --- a/extension-objects/pom.xml +++ b/extension-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/facade/pom.xml b/facade/pom.xml index 3847f8cbb..cf73e6a43 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT facade diff --git a/factory-kit/pom.xml b/factory-kit/pom.xml index 521e6340f..987bbdb24 100644 --- a/factory-kit/pom.xml +++ b/factory-kit/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT factory-kit diff --git a/factory-method/pom.xml b/factory-method/pom.xml index 8038a1ff9..c49fae691 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT factory-method diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index a44eae026..1818d882d 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/filterer/pom.xml b/filterer/pom.xml index e64ac9846..46042c1b0 100644 --- a/filterer/pom.xml +++ b/filterer/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 28e573258..138dbfa12 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/flux/pom.xml b/flux/pom.xml index 00435f835..14f4f5557 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT flux diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 574f5b516..b9ffd42ae 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT flyweight diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 447e341fd..a90029a82 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT front-controller diff --git a/game-loop/pom.xml b/game-loop/pom.xml index 33a671449..6935c1fd1 100644 --- a/game-loop/pom.xml +++ b/game-loop/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/guarded-suspension/pom.xml b/guarded-suspension/pom.xml index 81cf96084..f1bd31c66 100644 --- a/guarded-suspension/pom.xml +++ b/guarded-suspension/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT jar guarded-suspension diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index e101a849c..635b76172 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT half-sync-half-async diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml index 3a932749b..f51825d5f 100644 --- a/hexagonal/pom.xml +++ b/hexagonal/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT hexagonal diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index 59f82325a..d8ee9985f 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT intercepting-filter diff --git a/interpreter/pom.xml b/interpreter/pom.xml index d2d538c24..d32c80839 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT interpreter diff --git a/iterator/pom.xml b/iterator/pom.xml index 1d4faf770..bca091f11 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT iterator diff --git a/layers/pom.xml b/layers/pom.xml index d4b218272..9c299d2ba 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT com.iluwatar.layers layers diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index 1bfe3b637..49421edc2 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT lazy-loading diff --git a/leader-election/pom.xml b/leader-election/pom.xml index b61041502..78ad13e4d 100644 --- a/leader-election/pom.xml +++ b/leader-election/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT leader-election diff --git a/leader-followers/pom.xml b/leader-followers/pom.xml index 2e5789acc..42e552ac8 100644 --- a/leader-followers/pom.xml +++ b/leader-followers/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT leader-followers diff --git a/marker/pom.xml b/marker/pom.xml index 2e2ec74b5..64b7243f3 100644 --- a/marker/pom.xml +++ b/marker/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index 54a72da69..c6bc2facf 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT master-worker-pattern diff --git a/mediator/pom.xml b/mediator/pom.xml index ffae20778..ae802a349 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT mediator diff --git a/memento/pom.xml b/memento/pom.xml index 265825ccb..596883819 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT memento diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index 6e2e062d8..98c9dddfe 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT model-view-controller diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index 363dfd78c..ee309f292 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT model-view-presenter model-view-presenter diff --git a/module/pom.xml b/module/pom.xml index 4768ffcef..2dc3fe340 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT module diff --git a/monad/pom.xml b/monad/pom.xml index e74ee83eb..2c21a28b3 100644 --- a/monad/pom.xml +++ b/monad/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT monad diff --git a/monostate/pom.xml b/monostate/pom.xml index f00f7a677..02e271931 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT monostate diff --git a/multiton/pom.xml b/multiton/pom.xml index 8bb51845f..d1e4d50d5 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT multiton diff --git a/mute-idiom/pom.xml b/mute-idiom/pom.xml index 0d24529fa..2bf95f070 100644 --- a/mute-idiom/pom.xml +++ b/mute-idiom/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT mute-idiom diff --git a/mutex/pom.xml b/mutex/pom.xml index c08862948..84455abb1 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT mutex diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index 41cbd8571..1b1eb2266 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0 + 1.24.0-SNAPSHOT naked-objects-dom diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index 869af61f3..a918e20de 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0 + 1.24.0-SNAPSHOT naked-objects-fixture diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index f43b99197..b9482b292 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0 + 1.24.0-SNAPSHOT naked-objects-integtests diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index 0fc95946c..e8b9b79c5 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT naked-objects pom @@ -333,17 +333,17 @@ ${project.groupId} naked-objects-dom - 1.23.0 + 1.24.0-SNAPSHOT ${project.groupId} naked-objects-fixture - 1.23.0 + 1.24.0-SNAPSHOT ${project.groupId} naked-objects-webapp - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index 86960a5fb..3a817f9e2 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -30,7 +30,7 @@ com.iluwatar naked-objects - 1.23.0 + 1.24.0-SNAPSHOT naked-objects-webapp diff --git a/null-object/pom.xml b/null-object/pom.xml index e91b06f74..4317ee36a 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT null-object diff --git a/object-mother/pom.xml b/object-mother/pom.xml index 07d724e76..f9ca156ad 100644 --- a/object-mother/pom.xml +++ b/object-mother/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT object-mother diff --git a/object-pool/pom.xml b/object-pool/pom.xml index ed3f87a0d..0587c3968 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT object-pool diff --git a/observer/pom.xml b/observer/pom.xml index e971c5602..c558992ac 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT observer diff --git a/page-object/pom.xml b/page-object/pom.xml index 6c1066fce..a91843121 100644 --- a/page-object/pom.xml +++ b/page-object/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT page-object pom diff --git a/page-object/sample-application/pom.xml b/page-object/sample-application/pom.xml index c715418d5..6748a4063 100644 --- a/page-object/sample-application/pom.xml +++ b/page-object/sample-application/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT sample-application diff --git a/page-object/test-automation/pom.xml b/page-object/test-automation/pom.xml index f2ca98689..5f64807de 100644 --- a/page-object/test-automation/pom.xml +++ b/page-object/test-automation/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT test-automation diff --git a/partial-response/pom.xml b/partial-response/pom.xml index a4788e5d1..fbece028e 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/pipeline/pom.xml b/pipeline/pom.xml index a29007cda..fca6180bc 100644 --- a/pipeline/pom.xml +++ b/pipeline/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT pipeline diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index 38d12c6c7..c4780fe1b 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT poison-pill diff --git a/pom.xml b/pom.xml index 56c593574..56b955204 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT pom 2014-2019 diff --git a/priority-queue/pom.xml b/priority-queue/pom.xml index 338079a66..ff04a5359 100644 --- a/priority-queue/pom.xml +++ b/priority-queue/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index bc4eeff65..01d0149ea 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT private-class-data diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index 853eb68f8..4884ef728 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT producer-consumer diff --git a/promise/pom.xml b/promise/pom.xml index ac0f66a43..6ef67edec 100644 --- a/promise/pom.xml +++ b/promise/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT promise diff --git a/property/pom.xml b/property/pom.xml index e96371c9c..8746a60ac 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT property diff --git a/prototype/pom.xml b/prototype/pom.xml index 7fc26080a..220ed4521 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT prototype diff --git a/proxy/pom.xml b/proxy/pom.xml index 8d2749483..0e7707bf8 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT proxy diff --git a/queue-load-leveling/pom.xml b/queue-load-leveling/pom.xml index 8f9a785c9..817e6e3cc 100644 --- a/queue-load-leveling/pom.xml +++ b/queue-load-leveling/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT queue-load-leveling diff --git a/reactor/pom.xml b/reactor/pom.xml index 424c00db7..c25ed45ae 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT reactor diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index 10d49f6cc..37f70b435 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT reader-writer-lock diff --git a/repository/pom.xml b/repository/pom.xml index 5511c4fc3..694629efa 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT repository diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index 80d34e3aa..34428033b 100644 --- a/resource-acquisition-is-initialization/pom.xml +++ b/resource-acquisition-is-initialization/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT resource-acquisition-is-initialization diff --git a/retry/pom.xml b/retry/pom.xml index db59fa049..2f0b15bd2 100644 --- a/retry/pom.xml +++ b/retry/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT retry jar diff --git a/role-object/pom.xml b/role-object/pom.xml index 2b3e07be0..07becfc9b 100644 --- a/role-object/pom.xml +++ b/role-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT role-object diff --git a/saga/pom.xml b/saga/pom.xml index c83c8fb45..a3ae60ed8 100644 --- a/saga/pom.xml +++ b/saga/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT saga diff --git a/semaphore/pom.xml b/semaphore/pom.xml index 0a2ac7aed..64fd44db6 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT semaphore diff --git a/servant/pom.xml b/servant/pom.xml index e8925cea9..c7b282c09 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT servant diff --git a/serverless/pom.xml b/serverless/pom.xml index c9d7ec71b..2880764ec 100644 --- a/serverless/pom.xml +++ b/serverless/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT diff --git a/service-layer/pom.xml b/service-layer/pom.xml index aaee48310..071cf0f49 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT service-layer diff --git a/service-locator/pom.xml b/service-locator/pom.xml index ed2366ed0..2b0037eb8 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT service-locator diff --git a/sharding/pom.xml b/sharding/pom.xml index 61c15db5b..5f6c40ee5 100644 --- a/sharding/pom.xml +++ b/sharding/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/singleton/pom.xml b/singleton/pom.xml index 7b7686108..80a34ea86 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT singleton diff --git a/spatial-partition/pom.xml b/spatial-partition/pom.xml index 2f47d73d9..fe749b22b 100644 --- a/spatial-partition/pom.xml +++ b/spatial-partition/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT spatial-partition diff --git a/specification/pom.xml b/specification/pom.xml index d2945516b..1494ca305 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT specification diff --git a/state/pom.xml b/state/pom.xml index c53f3d797..a434dabe4 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT state diff --git a/step-builder/pom.xml b/step-builder/pom.xml index 1de9b653d..de5763695 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT step-builder diff --git a/strangler/pom.xml b/strangler/pom.xml index ba85f7184..7cb2ff263 100644 --- a/strangler/pom.xml +++ b/strangler/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/strategy/pom.xml b/strategy/pom.xml index aad38f1ce..0f3b0e830 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT strategy diff --git a/subclass-sandbox/pom.xml b/subclass-sandbox/pom.xml index 144f099a3..780547e95 100644 --- a/subclass-sandbox/pom.xml +++ b/subclass-sandbox/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/template-method/pom.xml b/template-method/pom.xml index 36a0d8550..cbf2ac156 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT template-method diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index abcb8a9f5..3727bd240 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT thread-pool diff --git a/throttling/pom.xml b/throttling/pom.xml index 77f911c24..ba2ca9c47 100644 --- a/throttling/pom.xml +++ b/throttling/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/tls/pom.xml b/tls/pom.xml index f6adc911f..54e911e40 100644 --- a/tls/pom.xml +++ b/tls/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT tls diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index 3324f75f0..6cc0ac283 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT tolerant-reader diff --git a/trampoline/pom.xml b/trampoline/pom.xml index c651b4f8b..fff117bf8 100644 --- a/trampoline/pom.xml +++ b/trampoline/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT trampoline diff --git a/transaction-script/pom.xml b/transaction-script/pom.xml index 081567c47..7a6f40219 100644 --- a/transaction-script/pom.xml +++ b/transaction-script/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/twin/pom.xml b/twin/pom.xml index 37c06bd20..b879ac593 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT twin diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index 32e252aea..03af8e78d 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT typeobjectpattern diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index 730b7921b..1d57e138f 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/update-method/pom.xml b/update-method/pom.xml index 2659d1e2c..3a60d433b 100644 --- a/update-method/pom.xml +++ b/update-method/pom.xml @@ -28,7 +28,7 @@ java-design-patterns com.iluwatar - 1.23.0 + 1.24.0-SNAPSHOT 4.0.0 diff --git a/value-object/pom.xml b/value-object/pom.xml index a2dd714de..dbbbccd01 100644 --- a/value-object/pom.xml +++ b/value-object/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT value-object diff --git a/visitor/pom.xml b/visitor/pom.xml index dddb4d4e3..a08f6ee8c 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.23.0 + 1.24.0-SNAPSHOT visitor From 9dd46d7b4a4329d07956b263dd627272e25db707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 25 Aug 2020 21:42:42 +0300 Subject: [PATCH 285/285] Update README.md --- builder/README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/builder/README.md b/builder/README.md index bb7426e35..008854ed7 100644 --- a/builder/README.md +++ b/builder/README.md @@ -9,36 +9,47 @@ tags: --- ## Intent -Separate the construction of a complex object from its -representation so that the same construction process can create different -representations. + +Separate the construction of a complex object from its representation so that the same construction +process can create different representations. ## Explanation Real world example -> Imagine a character generator for a role playing game. The easiest option is to let computer create the character for you. But if you want to select the character details like profession, gender, hair color etc. the character generation becomes a step-by-step process that completes when all the selections are ready. +> Imagine a character generator for a role-playing game. The easiest option is to let the computer +> create the character for you. If you want to manually select the character details like +> profession, gender, hair color etc. the character generation becomes a step-by-step process that +> completes when all the selections are ready. In plain words -> Allows you to create different flavors of an object while avoiding constructor pollution. Useful when there could be several flavors of an object. Or when there are a lot of steps involved in creation of an object. +> Allows you to create different flavors of an object while avoiding constructor pollution. Useful +> when there could be several flavors of an object. Or when there are a lot of steps involved in +> creation of an object. Wikipedia says -> The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor anti-pattern. +> The builder pattern is an object creation software design pattern with the intentions of finding +> a solution to the telescoping constructor anti-pattern. -Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point or the other we have all seen a constructor like below: +Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point +or the other, we have all seen a constructor like below: ```java public Hero(Profession profession, String name, HairType hairType, HairColor hairColor, Armor armor, Weapon weapon) { } ``` -As you can see the number of constructor parameters can quickly get out of hand and it might become difficult to understand the arrangement of parameters. Plus this parameter list could keep on growing if you would want to add more options in future. This is called telescoping constructor anti-pattern. +As you can see the number of constructor parameters can quickly get out of hand, and it may become +difficult to understand the arrangement of parameters. Plus this parameter list could keep on +growing if you would want to add more options in the future. This is called telescoping constructor +anti-pattern. **Programmatic Example** -The sane alternative is to use the Builder pattern. First of all we have our hero that we want to create +The sane alternative is to use the Builder pattern. First of all we have our hero that we want to +create: ```java public final class Hero { @@ -60,7 +71,7 @@ public final class Hero { } ``` -And then we have the builder +Then we have the builder: ```java public static class Builder { @@ -105,20 +116,22 @@ And then we have the builder } ``` -And then it can be used as: +Then it can be used as: ```java var mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build(); ``` ## Class diagram + ![alt text](./etc/builder.urm.png "Builder class diagram") ## Applicability + Use the Builder pattern when -* the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled -* the construction process must allow different representations for the object that's constructed +* The algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled +* The construction process must allow different representations for the object that's constructed ## Real world examples