From 0c6237c225584a3a28bdd81cb19a40de698ed7f7 Mon Sep 17 00:00:00 2001 From: AnaghaSasikumar <42939261+AnaghaSasikumar@users.noreply.github.com> Date: Thu, 25 Jul 2019 00:38:30 +0530 Subject: [PATCH 01/28] Type object pattern #555 (#848) * typeobject pattern * fixing errors * fix error cellpool * Update README.md * Update README.md --- pom.xml | 1 + typeobjectpattern/README.md | 29 +++ typeobjectpattern/pom.xml | 31 ++++ .../java/com/iluwatar/typeobject/App.java | 85 +++++++++ .../java/com/iluwatar/typeobject/Candy.java | 60 ++++++ .../com/iluwatar/typeobject/CandyGame.java | 171 ++++++++++++++++++ .../java/com/iluwatar/typeobject/Cell.java | 90 +++++++++ .../com/iluwatar/typeobject/CellPool.java | 96 ++++++++++ .../com/iluwatar/typeobject/JsonParser.java | 87 +++++++++ .../java/com/iluwatar/typeobject/candy.json | 45 +++++ .../iluwatar/typeobject/CandyGameTest.java | 69 +++++++ .../com/iluwatar/typeobject/CellPoolTest.java | 52 ++++++ .../com/iluwatar/typeobject/CellTest.java | 61 +++++++ 13 files changed, 877 insertions(+) create mode 100644 typeobjectpattern/README.md create mode 100644 typeobjectpattern/pom.xml create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java create mode 100644 typeobjectpattern/src/main/java/com/iluwatar/typeobject/candy.json create mode 100644 typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java create mode 100644 typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellPoolTest.java create mode 100644 typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java diff --git a/pom.xml b/pom.xml index 935efec53b64..014e67bda525 100644 --- a/pom.xml +++ b/pom.xml @@ -166,6 +166,7 @@ collection-pipeline master-worker-pattern spatial-partition + typeobjectpattern diff --git a/typeobjectpattern/README.md b/typeobjectpattern/README.md new file mode 100644 index 000000000000..97aa64e0b603 --- /dev/null +++ b/typeobjectpattern/README.md @@ -0,0 +1,29 @@ +--- +layout: pattern +title: Type-object +folder: typeobjectpattern +permalink: /patterns/typeobjectpattern/ +categories: Game Programming Patterns/Behavioral Patterns +tags: + - Java + - Difficulty-Beginner +--- + +## Intent +As explained in the book Game Programming Patterns by Robert Nystrom, type object pattern helps in + +> Allowing flexible creation of new “classes” by creating a single class, each instance of which represents a different type of object + +## Applicability +This pattern can be used when: +* We don’t know what types we will need up front. +* We want to be able to modify or add new types without having to recompile or change code. +* Only difference between the different 'types' of objects is the data, not the behaviour. + +## Explanation +Say, we are working on a game which has a hero and many monsters which are going to attack the hero. These monsters have certain attributes like attack, points etc. and come in different 'breeds' like zombie or ogres. The obvious answer is to have a base Monster class which has some fields and methods, which may be overriden by subclasses like the Zombie or Ogre class. But as we continue to build the game, there may be more and more breeds of monsters added and certain attributes may need to be changed in the existing monsters too. The OOP solution of inheriting from the base class would not be an efficient method in this case. +Using the type-object pattern, instead of creating many classes inheriting from a base class, we have 1 class with a field which represents the 'type' of object. This makes the code cleaner and object instantiation also becomes as easy as parsing a json file with the object properties. + +## Credits +* [Game Programming Patterns/Type Object](http://gameprogrammingpatterns.com/type-object.html) by Robert Nystrom +* [http://www.cs.sjsu.edu/~pearce/modules/patterns/analysis/top.htm] diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml new file mode 100644 index 000000000000..3377245f30ba --- /dev/null +++ b/typeobjectpattern/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.21.0-SNAPSHOT + + typeobjectpattern + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-core + test + + + \ No newline at end of file diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java new file mode 100644 index 000000000000..f16777c686a3 --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/App.java @@ -0,0 +1,85 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import java.io.FileNotFoundException; +import java.io.IOException; +import org.json.simple.parser.ParseException; + +/**

Type object pattern is the pattern we use when the OOP concept of creating a base class and + * inheriting from it just doesn't work for the case in hand. This happens when we either don't know + * what types we will need upfront, or want to be able to modify or add new types conveniently w/o + * recompiling repeatedly. The pattern provides a solution by allowing flexible creation of required + * objects by creating one class, which has a field which represents the 'type' of the object.

+ *

In this example, we have a mini candy-crush game in action. There are many different candies + * in the game, which may change over time, as we may want to upgrade the game. To make the object + * creation convenient, we have a class {@link Candy} which has a field name, parent, points and + * Type. We have a json file {@link candy} which contains the details about the candies, and this is + * parsed to get all the different candies in {@link JsonParser}. The {@link Cell} class is what the + * game matrix is made of, which has the candies that are to be crushed, and contains information on + * how crushing can be done, how the matrix is to be reconfigured and how points are to be gained. + * The {@link CellPool} class is a pool which reuses the candy cells that have been crushed instead + * of making new ones repeatedly. The {@link CandyGame} class has the rules for the continuation of + * the game and the {@link App} class has the game itself.

+ */ + +public class App { + + /** + * Program entry point. + * @param args command line args + */ + public static void main(String[] args) throws FileNotFoundException, IOException, ParseException { + int givenTime = 50; //50ms + int toWin = 500; //points + int pointsWon = 0; + int numOfRows = 3; + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis(); + int round = 0; + while (pointsWon < toWin && end - start < givenTime) { + round++; + CellPool pool = new CellPool(numOfRows * numOfRows + 5); + CandyGame cg = new CandyGame(numOfRows, pool); + if (round > 1) { + System.out.println("Refreshing.."); + } else { + System.out.println("Starting game.."); + } + cg.printGameStatus(); + end = System.currentTimeMillis(); + cg.round((int)(end - start), givenTime); + pointsWon += cg.totalPoints; + end = System.currentTimeMillis(); + } + System.out.println("Game Over"); + if (pointsWon >= toWin) { + System.out.println(pointsWon); + System.out.println("You win!!"); + } else { + System.out.println(pointsWon); + System.out.println("Sorry, you lose!"); + } + } +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java new file mode 100644 index 000000000000..40b276e5bbc5 --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Candy.java @@ -0,0 +1,60 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +/** + * The Candy class has a field type, which represents the 'type' of candy. The objects + * are created by parsing the candy.json file. + */ + +public class Candy { + + enum Type { crushableCandy, rewardFruit }; + + String name; + Candy parent; + String parentName; + private int points; + private Type type; + + Candy(String name, String parentName, Type type, int points) { + this.name = name; + this.parent = null; + this.type = type; + this.points = points; + this.parentName = parentName; + } + + int getPoints() { + return this.points; + } + + void setPoints(int a) { + this.points = a; + } + + Type getType() { + return this.type; + } +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java new file mode 100644 index 000000000000..a2ba452ec03a --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CandyGame.java @@ -0,0 +1,171 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import java.util.ArrayList; +import com.iluwatar.typeobject.Candy.Type; + +/** + * The CandyGame class contains the rules for the continuation of the game and has + * the game matrix (field 'cells') and totalPoints gained during the game. + */ + +public class CandyGame { + Cell[][] cells; + CellPool pool; + int totalPoints; + + CandyGame(int num, CellPool pool) { + this.cells = new Cell[num][num]; + this.pool = pool; + this.totalPoints = 0; + for (int i = 0; i < num; i++) { + for (int j = 0; j < num; j++) { + this.cells[i][j] = this.pool.getNewCell(); + this.cells[i][j].xIndex = j; + this.cells[i][j].yIndex = i; + } + } + } + + static String numOfSpaces(int num) { + String result = ""; + for (int i = 0; i < num; i++) { + result += " "; + } + return result; + } + + void printGameStatus() { + System.out.println(""); + for (int i = 0; i < cells.length; i++) { + for (int j = 0; j < cells.length; j++) { + String candyName = cells[i][j].candy.name; + if (candyName.length() < 20) { + int totalSpaces = 20 - candyName.length(); + System.out.print(numOfSpaces(totalSpaces / 2) + cells[i][j].candy.name + + numOfSpaces(totalSpaces - totalSpaces / 2) + "|"); + } else { + System.out.print(candyName + "|"); + } + } + System.out.println(""); + } + System.out.println(""); + } + + ArrayList adjacentCells(int yIndex, int xIndex) { + ArrayList adjacent = new ArrayList(); + if (yIndex == 0) { + adjacent.add(this.cells[1][xIndex]); + } + if (xIndex == 0) { + adjacent.add(this.cells[yIndex][1]); + } + if (yIndex == cells.length - 1) { + adjacent.add(this.cells[cells.length - 2][xIndex]); + } + if (xIndex == cells.length - 1) { + adjacent.add(this.cells[yIndex][cells.length - 2]); + } + if (yIndex > 0 && yIndex < cells.length - 1) { + adjacent.add(this.cells[yIndex - 1][xIndex]); + adjacent.add(this.cells[yIndex + 1][xIndex]); + } + if (xIndex > 0 && xIndex < cells.length - 1) { + adjacent.add(this.cells[yIndex][xIndex - 1]); + adjacent.add(this.cells[yIndex][xIndex + 1]); + } + return adjacent; + } + + boolean continueRound() { + for (int i = 0; i < this.cells.length; i++) { + if (this.cells[cells.length - 1][i].candy.getType().equals(Type.rewardFruit)) { + return true; + } + } + for (int i = 0; i < this.cells.length; i++) { + for (int j = 0; j < this.cells.length; j++) { + if (!this.cells[i][j].candy.getType().equals(Type.rewardFruit)) { + ArrayList adj = adjacentCells(i,j); + for (int a = 0; a < adj.size(); a++) { + if (this.cells[i][j].candy.name.equals(adj.get(a).candy.name)) { + return true; + } + } + } + } + } + return false; + } + + void handleChange(int points) { + System.out.println("+" + points + " points!"); + this.totalPoints += points; + printGameStatus(); + } + + void round(int timeSoFar, int totalTime) { + long start = System.currentTimeMillis(); + long end = System.currentTimeMillis(); + while (end - start + timeSoFar < totalTime && continueRound()) { + for (int i = 0; i < this.cells.length; i++) { + int points = 0; + int j = this.cells.length - 1; + while (this.cells[j][i].candy.getType().equals(Type.rewardFruit)) { + points = this.cells[j][i].candy.getPoints(); + this.cells[j][i].crush(pool, this.cells); + handleChange(points); + } + } + for (int i = 0; i < this.cells.length; i++) { + int j = cells.length - 1; + int points = 0; + while (j > 0) { + points = this.cells[j][i].interact(this.cells[j - 1][i], this.pool, this.cells); + if (points != 0) { + handleChange(points); + } else { + j = j - 1; + } + } + } + for (int i = 0; i < this.cells.length; i++) { + int j = 0; + int points = 0; + while (j < cells.length - 1) { + points = this.cells[i][j].interact(this.cells[i][j + 1], this.pool, this.cells); + if (points != 0) { + handleChange(points); + } else { + j = j + 1; + } + } + } + end = System.currentTimeMillis(); + } + } + +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java new file mode 100644 index 000000000000..7d0d696430fd --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/Cell.java @@ -0,0 +1,90 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import com.iluwatar.typeobject.Candy.Type; + +/** + * The Cell object is what the game matrix is made of and contains the candy which is + * to be crushed or collected as reward. + */ + +public class Cell { + Candy candy; + int xIndex; + int yIndex; + + Cell(Candy candy, int xIndex, int yIndex) { + this.candy = candy; + this.xIndex = xIndex; + this.yIndex = yIndex; + } + + Cell() { + this.candy = null; + this.xIndex = 0; + this.yIndex = 0; + } + + void crush(CellPool pool, Cell[][] cellMatrix) { + //take out from this position and put back in pool + pool.addNewCell(this); + this.fillThisSpace(pool, cellMatrix); + } + + void fillThisSpace(CellPool pool, Cell[][] cellMatrix) { + for (int y = this.yIndex; y > 0; y--) { + cellMatrix[y][this.xIndex] = cellMatrix[y - 1][this.xIndex]; + cellMatrix[y][this.xIndex].yIndex = y; + } + Cell newC = pool.getNewCell(); + cellMatrix[0][this.xIndex] = newC; + cellMatrix[0][this.xIndex].xIndex = this.xIndex; + cellMatrix[0][this.xIndex].yIndex = 0; + } + + void handleCrush(Cell c, CellPool pool, Cell[][] cellMatrix) { + if (this.yIndex >= c.yIndex) { + this.crush(pool, cellMatrix); + c.crush(pool, cellMatrix); + } else { + c.crush(pool, cellMatrix); + this.crush(pool, cellMatrix); + } + } + + int interact(Cell c, CellPool pool, Cell[][] cellMatrix) { + if (this.candy.getType().equals(Type.rewardFruit) || c.candy.getType().equals(Type.rewardFruit)) { + return 0; + } else { + if (this.candy.name.equals(c.candy.name)) { + int pointsWon = this.candy.getPoints() + c.candy.getPoints(); + handleCrush(c,pool,cellMatrix); + return pointsWon; + } else { + return 0; + } + } + } +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java new file mode 100644 index 000000000000..88263ceab57d --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/CellPool.java @@ -0,0 +1,96 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Random; +import org.json.simple.parser.ParseException; +import com.iluwatar.typeobject.Candy.Type; + +/** + * The CellPool class allows the reuse of crushed cells instead of creation of new + * cells each time. The reused cell is given a new candy to hold using the randomCode + * field which holds all the candies available. + */ + +public class CellPool { + ArrayList pool; + int pointer; + Candy[] randomCode; + + CellPool(int num) { + this.pool = new ArrayList(num); + try { + this.randomCode = assignRandomCandytypes(); + } catch (Exception e) { + 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); + } + for (int i = 0; i < num; i++) { + Cell c = new Cell(); + Random rand = new Random(); + c.candy = randomCode[rand.nextInt(randomCode.length)]; + this.pool.add(c); + } + this.pointer = num - 1; + } + + Cell getNewCell() { + Cell newCell = this.pool.remove(pointer); + pointer--; + return newCell; + } + + void addNewCell(Cell c) { + Random rand = new Random(); + c.candy = randomCode[rand.nextInt(randomCode.length)]; //changing candytype to new + this.pool.add(c); + pointer++; + } + + Candy[] assignRandomCandytypes() throws FileNotFoundException, IOException, ParseException { + JsonParser jp = new JsonParser(); + jp.parse(); + Candy[] randomCode = new Candy[jp.candies.size() - 2]; //exclude generic types 'fruit' and 'candy' + int i = 0; + for (Enumeration e = jp.candies.keys(); e.hasMoreElements();) { + String s = e.nextElement(); + if (!s.equals("fruit") && !s.equals("candy")) { + //not generic + randomCode[i] = jp.candies.get(s); + i++; + } + } + return randomCode; + } +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java new file mode 100644 index 000000000000..6c6bfa616a34 --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/JsonParser.java @@ -0,0 +1,87 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Hashtable; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import com.iluwatar.typeobject.Candy.Type; + +/** + * The JsonParser class helps parse the json file candy.json to get all the + * different candies. + */ + +public class JsonParser { + Hashtable candies; + + JsonParser() { + this.candies = new Hashtable(); + } + + void parse() throws FileNotFoundException, IOException, ParseException { + JSONParser parser = new JSONParser(); + JSONObject jo = (JSONObject) parser.parse(new FileReader(new File("").getAbsolutePath() + + "\\src\\main\\java\\com\\iluwatar\\typeobject\\candy.json")); + JSONArray a = (JSONArray) jo.get("candies"); + for (Object o : a) { + JSONObject candy = (JSONObject) o; + String name = (String) candy.get("name"); + String parentName = (String) candy.get("parent"); + String t = (String) candy.get("type"); + Type type = null; + if (t.equals("rewardFruit")) { + type = Type.rewardFruit; + } else { + type = Type.crushableCandy; + } + int points = Integer.parseInt((String) candy.get("points")); + Candy c = new Candy(name, parentName, type, points); + this.candies.put(name, c); + } + setParentAndPoints(); + } + + void setParentAndPoints() { + for (Enumeration e = this.candies.keys(); e.hasMoreElements();) { + Candy c = this.candies.get(e.nextElement()); + if (c.parentName == null) { + c.parent = null; + } else { + c.parent = this.candies.get(c.parentName); + } + if (c.getPoints() == 0 && c.parent != null) { + c.setPoints(c.parent.getPoints()); + } + } + } + +} diff --git a/typeobjectpattern/src/main/java/com/iluwatar/typeobject/candy.json b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/candy.json new file mode 100644 index 000000000000..74430c318d72 --- /dev/null +++ b/typeobjectpattern/src/main/java/com/iluwatar/typeobject/candy.json @@ -0,0 +1,45 @@ +{"candies" : [ + { + "name" : "fruit", + "parent" : "null", + "type" : "rewardFruit", + "points" : "20" + }, + { + "name" : "candy", + "parent" : "null", + "type" : "crushableCandy", + "points" : "10" + }, + { + "name" : "cherry", + "parent" : "fruit", + "type" : "rewardFruit", + "points" : "0" + }, + { + "name" : "mango", + "parent" : "fruit", + "type" : "rewardFruit", + "points" : "0" + }, + { + "name" : "purple popsicle", + "parent" : "candy", + "type" : "crushableCandy", + "points" : "0" + }, + { + "name" : "green jellybean", + "parent" : "candy", + "type" : "crushableCandy", + "points" : "0" + }, + { + "name" : "orange gum", + "parent" : "candy", + "type" : "crushableCandy", + "points" : "0" + } + ] +} diff --git a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java new file mode 100644 index 000000000000..d1b2fd359385 --- /dev/null +++ b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CandyGameTest.java @@ -0,0 +1,69 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import com.iluwatar.typeobject.Candy.Type; + +/** + * The CandyGameTest class tests the methods in the {@link CandyGame} class. + */ + +class CandyGameTest { + + @Test + void adjacentCellsTest() { + CandyGame cg = new CandyGame(3,new CellPool(9)); + ArrayList arr1 = cg.adjacentCells(0, 0); + ArrayList arr2 = cg.adjacentCells(1, 2); + ArrayList arr3 = cg.adjacentCells(1, 1); + assertTrue(arr1.size() == 2 && arr2.size() == 3 && arr3.size() == 4); + } + + @Test + void continueRoundTest() { + Cell[][] matrix = new Cell[2][2]; + Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); + Candy c2 = new Candy("purple jelly", "jelly", Type.crushableCandy, 5); + Candy c3 = new Candy("green apple", "apple", Type.rewardFruit, 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); + matrix[1][1] = new Cell(c2,1,1); + CellPool p = new CellPool(4); + CandyGame cg = new CandyGame(2,p); + cg.cells = matrix; + boolean fruitInLastRow = cg.continueRound(); + matrix[1][0].crush(p, matrix); + matrix[0][0] = new Cell(c3,0,0); + boolean matchingCandy = cg.continueRound(); + matrix[0][1].crush(p,matrix); + matrix[0][1] = new Cell(c3,1,0); + boolean noneLeft = cg.continueRound(); + assertTrue(fruitInLastRow && matchingCandy && !noneLeft); + } + +} diff --git a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellPoolTest.java b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellPoolTest.java new file mode 100644 index 000000000000..437e39d1abd3 --- /dev/null +++ b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellPoolTest.java @@ -0,0 +1,52 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import java.util.Hashtable; + +/** + * The CellPoolTest class tests the methods in the {@link CellPool} class. + */ + +class CellPoolTest { + + @Test + void assignRandomCandyTypesTest() { + CellPool cp = new CellPool(10); + Hashtable ht = new Hashtable(); + int parentTypes = 0; + for (int i = 0; i < cp.randomCode.length; i++) { + if (ht.get(cp.randomCode[i].name) == null) { + ht.put(cp.randomCode[i].name, true); + } + if (cp.randomCode[i].name.equals("fruit") || cp.randomCode[i].name.equals("candy")) { + parentTypes++; + } + } + assertTrue(ht.size() == 5 && parentTypes == 0); + } + +} diff --git a/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java new file mode 100644 index 000000000000..b4118cb48651 --- /dev/null +++ b/typeobjectpattern/src/test/java/com/iluwatar/typeobject/CellTest.java @@ -0,0 +1,61 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.typeobject; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import com.iluwatar.typeobject.Candy.Type; + +/** + * The CellTest class tests the methods in the {@link Cell} class. + */ + +class CellTest { + + @Test + void interactTest() { + Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); + Candy c2 = new Candy("green apple", "apple", Type.rewardFruit, 10); + Cell[][] matrix = new Cell[4][4]; + matrix[0][0] = new Cell(c1,0,0); + matrix[0][1] = new Cell(c1,1,0); + matrix[0][2] = new Cell(c2,2,0); + matrix[0][3] = new Cell(c1,3,0); + CellPool cp = new CellPool(5); + int points1 = matrix[0][0].interact(matrix[0][1], cp, matrix); + int points2 = matrix[0][2].interact(matrix[0][3], cp, matrix); + assertTrue(points1 > 0 && points2 == 0); + } + + @Test + void crushTest() { + Candy c1 = new Candy("green jelly", "jelly", Type.crushableCandy, 5); + Candy c2 = new Candy("purple candy", "candy", Type.crushableCandy, 5); + Cell[][] matrix = new Cell[4][4]; + matrix[0][0] = new Cell(c1,0,0); + matrix[1][0] = new Cell(c2,0,1); + matrix[1][0].crush(new CellPool(5), matrix); + assertTrue(matrix[1][0].candy.name.equals("green jelly")); + } +} From 17bfc91f4532ab06d48bbfed5c2f9ad030a80651 Mon Sep 17 00:00:00 2001 From: ptrax Date: Sun, 28 Jul 2019 06:20:18 -0500 Subject: [PATCH 02/28] Change Travis CI build env. to Trusty (#911) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 85f53bcd3024..58edddeb416e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: java +dist: trusty # Xenial build environment won't allow installation of Java 8 jdk: - oraclejdk8 From c6ecf58687b8fa76bdfa933f67f25d299b55126c Mon Sep 17 00:00:00 2001 From: kanwarpreet25 <39183641+kanwarpreet25@users.noreply.github.com> Date: Sun, 28 Jul 2019 18:09:40 +0530 Subject: [PATCH 03/28] 508 : sonar qube critical issue fixes (#852) * 508 : sonar qube critical issue fixes * 508 : Sunar Qube Fixes Define a constant instead of duplicating this literal "user_accounts" 4 times. Define a constant instead of duplicating this literal "userID" 5 times Define a constant instead of duplicating this literal "additionalInfo" 4 times. Define a constant instead of duplicating this literal "userName" 4 times. * 508 : Sunar Qube Fixes Define a constant instead of duplicating this literal "user_accounts" 4 times. * 508 : Sonar Qube Fixes Define a constant instead of duplicating this literal "eEvans" 4 times Define a constant instead of duplicating this literal "jBloch" 6 times Define a constant instead of duplicating this literal "mFowler" 3 times * 508 : Sonar Qube FIxes Define a constant instead of duplicating this literal "username" 3 times. * 508: sonar qube issue fixes Define a constant instead of duplicating this literal "customerDao.getAllCustomers(): " 4 times. * 508 : sonar qube issue fixes Define a constant instead of duplicating this literal "App.main(), student : " 4 times. * 508 : sonar Qube issue fixes Define a constant instead of duplicating this literal "{} hits {}. {} is damaged!" 3 times. Define a constant instead of duplicating this literal "{} hits {}." 4 times. * 508 : Define a constant instead of duplicating this literal "{} hits {}." 4 times. * 508 : checkstyle fixes * 508: checkstyle fixes * 508: checkstyle fixes * 508: checkstyle fixes * 508: checkstyle fixes * 508: checkstyle fixes * 508: cqrs checkstyle fixes --- .../com/iluwatar/abstractdocument/App.java | 32 +++++++++---------- .../abstractdocument/domain/HasModel.java | 5 ++- .../abstractdocument/domain/HasParts.java | 4 +-- .../abstractdocument/domain/HasPrice.java | 4 +-- .../abstractdocument/domain/HasType.java | 8 ++--- .../domain/enums/Property.java | 11 +++++++ .../iluwatar/abstractdocument/DomainTest.java | 26 +++++++-------- .../java/com/iluwatar/caching/DbManager.java | 29 +++++++++-------- .../caching/constants/CachingConstants.java | 15 +++++++++ .../main/java/com/iluwatar/cqrs/app/App.java | 27 ++++++++-------- .../iluwatar/cqrs/constants/AppConstants.java | 15 +++++++++ .../cqrs/queries/QueryServiceImpl.java | 7 ++-- dao/src/main/java/com/iluwatar/dao/App.java | 9 +++--- .../java/com/iluwatar/datamapper/App.java | 10 +++--- .../iluwatar/doubledispatch/Meteoroid.java | 10 +++--- .../doubledispatch/SpaceStationMir.java | 10 +++--- .../constants/AppConstants.java | 11 +++++++ 17 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java create mode 100644 caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java create mode 100644 cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java create mode 100644 double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java 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 83f6ab3d59dd..c0dbbff4755b 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/App.java @@ -22,18 +22,16 @@ */ package com.iluwatar.abstractdocument; -import com.iluwatar.abstractdocument.domain.Car; -import com.iluwatar.abstractdocument.domain.HasModel; -import com.iluwatar.abstractdocument.domain.HasParts; -import com.iluwatar.abstractdocument.domain.HasPrice; -import com.iluwatar.abstractdocument.domain.HasType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.iluwatar.abstractdocument.domain.Car; +import com.iluwatar.abstractdocument.domain.enums.Property; + /** * The Abstract Document pattern enables handling additional, non-static * properties. This pattern uses concept of traits to enable type safety and @@ -55,20 +53,20 @@ public App() { LOGGER.info("Constructing parts and car"); Map carProperties = new HashMap<>(); - carProperties.put(HasModel.PROPERTY, "300SL"); - carProperties.put(HasPrice.PROPERTY, 10000L); + carProperties.put(Property.MODEL.toString(), "300SL"); + carProperties.put(Property.PRICE.toString(), 10000L); Map wheelProperties = new HashMap<>(); - wheelProperties.put(HasType.PROPERTY, "wheel"); - wheelProperties.put(HasModel.PROPERTY, "15C"); - wheelProperties.put(HasPrice.PROPERTY, 100L); + wheelProperties.put(Property.TYPE.toString(), "wheel"); + wheelProperties.put(Property.MODEL.toString(), "15C"); + wheelProperties.put(Property.PRICE.toString(), 100L); Map doorProperties = new HashMap<>(); - doorProperties.put(HasType.PROPERTY, "door"); - doorProperties.put(HasModel.PROPERTY, "Lambo"); - doorProperties.put(HasPrice.PROPERTY, 300L); + doorProperties.put(Property.TYPE.toString(), "door"); + doorProperties.put(Property.MODEL.toString(), "Lambo"); + doorProperties.put(Property.PRICE.toString(), 300L); - carProperties.put(HasParts.PROPERTY, Arrays.asList(wheelProperties, doorProperties)); + carProperties.put(Property.PARTS.toString(), Arrays.asList(wheelProperties, doorProperties)); Car car = new Car(carProperties); diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java index 252a4644f289..3f2c40df8183 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java @@ -25,16 +25,15 @@ import java.util.Optional; import com.iluwatar.abstractdocument.Document; +import com.iluwatar.abstractdocument.domain.enums.Property; /** * HasModel trait for static access to 'model' property */ public interface HasModel extends Document { - String PROPERTY = "model"; - default Optional getModel() { - return Optional.ofNullable((String) get(PROPERTY)); + return Optional.ofNullable((String) get(Property.MODEL.toString())); } } 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 9df836376f55..cf6ec6b01ccf 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 @@ -25,16 +25,16 @@ import java.util.stream.Stream; import com.iluwatar.abstractdocument.Document; +import com.iluwatar.abstractdocument.domain.enums.Property; /** * HasParts trait for static access to 'parts' property */ public interface HasParts extends Document { - String PROPERTY = "parts"; default Stream getParts() { - return children(PROPERTY, Part::new); + 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 39e4d159ce58..ca2e9018966c 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 @@ -25,16 +25,16 @@ import java.util.Optional; import com.iluwatar.abstractdocument.Document; +import com.iluwatar.abstractdocument.domain.enums.Property; /** * HasPrice trait for static access to 'price' property */ public interface HasPrice extends Document { - String PROPERTY = "price"; default Optional getPrice() { - return Optional.ofNullable((Number) get(PROPERTY)); + 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 4a80bff20c16..1dfb36ab21b6 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 @@ -22,19 +22,19 @@ */ package com.iluwatar.abstractdocument.domain; -import com.iluwatar.abstractdocument.Document; - import java.util.Optional; +import com.iluwatar.abstractdocument.Document; +import com.iluwatar.abstractdocument.domain.enums.Property; + /** * HasType trait for static access to 'type' property */ public interface HasType extends Document { - String PROPERTY = "type"; default Optional getType() { - return Optional.ofNullable((String) get(PROPERTY)); + return Optional.ofNullable((String) get(Property.TYPE.toString())); } } diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java new file mode 100644 index 000000000000..b766141a87f2 --- /dev/null +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java @@ -0,0 +1,11 @@ +package com.iluwatar.abstractdocument.domain.enums; + +/** + * + * Enum To Describe Property type + * + */ +public enum Property { + + PARTS, TYPE, PRICE, MODEL +} diff --git a/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java b/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java index 891e5a45763e..4c2a1c0d1ca7 100644 --- a/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java +++ b/abstract-document/src/test/java/com/iluwatar/abstractdocument/DomainTest.java @@ -22,19 +22,17 @@ */ package com.iluwatar.abstractdocument; -import com.iluwatar.abstractdocument.domain.Car; -import com.iluwatar.abstractdocument.domain.HasModel; -import com.iluwatar.abstractdocument.domain.HasParts; -import com.iluwatar.abstractdocument.domain.HasPrice; -import com.iluwatar.abstractdocument.domain.HasType; -import com.iluwatar.abstractdocument.domain.Part; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +import com.iluwatar.abstractdocument.domain.Car; +import com.iluwatar.abstractdocument.domain.Part; +import com.iluwatar.abstractdocument.domain.enums.Property; /** * Test for Part and Car @@ -51,9 +49,9 @@ public class DomainTest { @Test public void shouldConstructPart() { Map partProperties = new HashMap<>(); - partProperties.put(HasType.PROPERTY, TEST_PART_TYPE); - partProperties.put(HasModel.PROPERTY, TEST_PART_MODEL); - partProperties.put(HasPrice.PROPERTY, TEST_PART_PRICE); + partProperties.put(Property.TYPE.toString(), TEST_PART_TYPE); + partProperties.put(Property.MODEL.toString(), TEST_PART_MODEL); + partProperties.put(Property.PRICE.toString(), TEST_PART_PRICE); Part part = new Part(partProperties); assertEquals(TEST_PART_TYPE, part.getType().get()); @@ -64,9 +62,9 @@ public void shouldConstructPart() { @Test public void shouldConstructCar() { Map carProperties = new HashMap<>(); - carProperties.put(HasModel.PROPERTY, TEST_CAR_MODEL); - carProperties.put(HasPrice.PROPERTY, TEST_CAR_PRICE); - carProperties.put(HasParts.PROPERTY, Arrays.asList(new HashMap<>(), new HashMap<>())); + carProperties.put(Property.MODEL.toString(), TEST_CAR_MODEL); + carProperties.put(Property.PRICE.toString(), TEST_CAR_PRICE); + carProperties.put(Property.PARTS.toString(), Arrays.asList(new HashMap<>(), new HashMap<>())); Car car = new Car(carProperties); assertEquals(TEST_CAR_MODEL, car.getModel().get()); diff --git a/caching/src/main/java/com/iluwatar/caching/DbManager.java b/caching/src/main/java/com/iluwatar/caching/DbManager.java index 6fccaf43e5ff..9de45a17ee38 100644 --- a/caching/src/main/java/com/iluwatar/caching/DbManager.java +++ b/caching/src/main/java/com/iluwatar/caching/DbManager.java @@ -28,6 +28,7 @@ import org.bson.Document; +import com.iluwatar.caching.constants.CachingConstants; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoDatabase; @@ -90,12 +91,12 @@ public static UserAccount readFromDb(String userId) { } } FindIterable iterable = - db.getCollection("user_accounts").find(new Document("userID", userId)); + db.getCollection(CachingConstants.USER_ACCOUNT).find(new Document(CachingConstants.USER_ID, userId)); if (iterable == null) { return null; } Document doc = iterable.first(); - return new UserAccount(userId, doc.getString("userName"), doc.getString("additionalInfo")); + return new UserAccount(userId, doc.getString(CachingConstants.USER_NAME), doc.getString(CachingConstants.ADD_INFO)); } /** @@ -113,9 +114,9 @@ public static void writeToDb(UserAccount userAccount) { e.printStackTrace(); } } - db.getCollection("user_accounts").insertOne( - new Document("userID", userAccount.getUserId()).append("userName", - userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())); + db.getCollection(CachingConstants.USER_ACCOUNT).insertOne( + new Document(CachingConstants.USER_ID ,userAccount.getUserId()).append(CachingConstants.USER_NAME, + userAccount.getUserName()).append(CachingConstants.ADD_INFO, userAccount.getAdditionalInfo())); } /** @@ -133,10 +134,10 @@ public static void updateDb(UserAccount userAccount) { e.printStackTrace(); } } - db.getCollection("user_accounts").updateOne( - new Document("userID", userAccount.getUserId()), - new Document("$set", new Document("userName", userAccount.getUserName()).append( - "additionalInfo", userAccount.getAdditionalInfo()))); + db.getCollection(CachingConstants.USER_ACCOUNT).updateOne( + new Document(CachingConstants.USER_ID, userAccount.getUserId()), + new Document("$set", new Document(CachingConstants.USER_NAME, userAccount.getUserName()) + .append(CachingConstants.ADD_INFO, userAccount.getAdditionalInfo()))); } /** @@ -155,10 +156,12 @@ public static void upsertDb(UserAccount userAccount) { e.printStackTrace(); } } - db.getCollection("user_accounts").updateOne( - new Document("userID", userAccount.getUserId()), - new Document("$set", new Document("userID", userAccount.getUserId()).append("userName", - userAccount.getUserName()).append("additionalInfo", userAccount.getAdditionalInfo())), + db.getCollection(CachingConstants.USER_ACCOUNT).updateOne( + new Document(CachingConstants.USER_ID, userAccount.getUserId()), + new Document("$set", + new Document(CachingConstants.USER_ID, userAccount.getUserId()) + .append(CachingConstants.USER_NAME, userAccount.getUserName()).append(CachingConstants.ADD_INFO, + userAccount.getAdditionalInfo())), new UpdateOptions().upsert(true)); } } diff --git a/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java b/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java new file mode 100644 index 000000000000..cc5e34e2d2b0 --- /dev/null +++ b/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java @@ -0,0 +1,15 @@ +package com.iluwatar.caching.constants; + +/** + * + * Constant class for defining constants + * + */ +public class CachingConstants { + + public static final String USER_ACCOUNT = "user_accounts"; + public static final String USER_ID = "userID"; + public static final String USER_NAME = "userName"; + public static final String ADD_INFO = "additionalInfo"; + +} diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java b/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java index a943a7f88891..0f766e5c727f 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java @@ -30,6 +30,7 @@ import com.iluwatar.cqrs.commandes.CommandServiceImpl; import com.iluwatar.cqrs.commandes.ICommandService; +import com.iluwatar.cqrs.constants.AppConstants; import com.iluwatar.cqrs.dto.Author; import com.iluwatar.cqrs.dto.Book; import com.iluwatar.cqrs.queries.IQueryService; @@ -60,27 +61,27 @@ public static void main(String[] args) { ICommandService commands = new CommandServiceImpl(); // Create Authors and Books using CommandService - commands.authorCreated("eEvans", "Eric Evans", "eEvans@email.com"); - commands.authorCreated("jBloch", "Joshua Bloch", "jBloch@email.com"); - commands.authorCreated("mFowler", "Martin Fowler", "mFowler@email.com"); + commands.authorCreated(AppConstants.E_EVANS, "Eric Evans", "eEvans@email.com"); + commands.authorCreated(AppConstants.J_BLOCH, "Joshua Bloch", "jBloch@email.com"); + commands.authorCreated(AppConstants.M_FOWLER, "Martin Fowler", "mFowler@email.com"); - commands.bookAddedToAuthor("Domain-Driven Design", 60.08, "eEvans"); - commands.bookAddedToAuthor("Effective Java", 40.54, "jBloch"); - commands.bookAddedToAuthor("Java Puzzlers", 39.99, "jBloch"); - commands.bookAddedToAuthor("Java Concurrency in Practice", 29.40, "jBloch"); - commands.bookAddedToAuthor("Patterns of Enterprise Application Architecture", 54.01, "mFowler"); - commands.bookAddedToAuthor("Domain Specific Languages", 48.89, "mFowler"); - commands.authorNameUpdated("eEvans", "Eric J. Evans"); + commands.bookAddedToAuthor("Domain-Driven Design", 60.08, AppConstants.E_EVANS); + commands.bookAddedToAuthor("Effective Java", 40.54, AppConstants.J_BLOCH); + commands.bookAddedToAuthor("Java Puzzlers", 39.99, AppConstants.J_BLOCH); + commands.bookAddedToAuthor("Java Concurrency in Practice", 29.40, AppConstants.J_BLOCH); + commands.bookAddedToAuthor("Patterns of Enterprise Application Architecture", 54.01, AppConstants.M_FOWLER); + commands.bookAddedToAuthor("Domain Specific Languages", 48.89, AppConstants.M_FOWLER); + commands.authorNameUpdated(AppConstants.E_EVANS, "Eric J. Evans"); IQueryService queries = new QueryServiceImpl(); // Query the database using QueryService Author nullAuthor = queries.getAuthorByUsername("username"); - Author eEvans = queries.getAuthorByUsername("eEvans"); - BigInteger jBlochBooksCount = queries.getAuthorBooksCount("jBloch"); + Author eEvans = queries.getAuthorByUsername(AppConstants.E_EVANS); + BigInteger jBlochBooksCount = queries.getAuthorBooksCount(AppConstants.J_BLOCH); BigInteger authorsCount = queries.getAuthorsCount(); Book dddBook = queries.getBook("Domain-Driven Design"); - List jBlochBooks = queries.getAuthorBooks("jBloch"); + List jBlochBooks = queries.getAuthorBooks(AppConstants.J_BLOCH); LOGGER.info("Author username : {}", nullAuthor); LOGGER.info("Author eEvans : {}", eEvans); diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java b/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java new file mode 100644 index 000000000000..154d63a892cf --- /dev/null +++ b/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java @@ -0,0 +1,15 @@ +package com.iluwatar.cqrs.constants; + +/** + * + * Class to define the constants + * + */ +public class AppConstants { + + public static final String E_EVANS = "eEvans"; + public static final String J_BLOCH = "jBloch"; + public static final String M_FOWLER = "mFowler"; + public static final String USER_NAME = "username"; + +} 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 dc44d0f1b7c8..86eb4dd2f351 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java @@ -30,6 +30,7 @@ import org.hibernate.SessionFactory; import org.hibernate.transform.Transformers; +import com.iluwatar.cqrs.constants.AppConstants; import com.iluwatar.cqrs.dto.Author; import com.iluwatar.cqrs.dto.Book; import com.iluwatar.cqrs.util.HibernateUtil; @@ -50,7 +51,7 @@ public Author getAuthorByUsername(String username) { SQLQuery sqlQuery = session .createSQLQuery("SELECT a.username as \"username\", a.name as \"name\", a.email as \"email\"" + "FROM Author a where a.username=:username"); - sqlQuery.setParameter("username", username); + sqlQuery.setParameter(AppConstants.USER_NAME, username); authorDTo = (Author) sqlQuery.setResultTransformer(Transformers.aliasToBean(Author.class)).uniqueResult(); } return authorDTo; @@ -74,7 +75,7 @@ public List getAuthorBooks(String username) { try (Session session = sessionFactory.openSession()) { SQLQuery sqlQuery = session.createSQLQuery("SELECT b.title as \"title\", b.price as \"price\"" + " FROM Author a , Book b where b.author_id = a.id and a.username=:username"); - sqlQuery.setParameter("username", username); + sqlQuery.setParameter(AppConstants.USER_NAME, username); bookDTos = sqlQuery.setResultTransformer(Transformers.aliasToBean(Book.class)).list(); } return bookDTos; @@ -86,7 +87,7 @@ public BigInteger getAuthorBooksCount(String username) { try (Session session = sessionFactory.openSession()) { SQLQuery sqlQuery = session.createSQLQuery( "SELECT count(b.title)" + " FROM Book b, Author a where b.author_id = a.id and a.username=:username"); - sqlQuery.setParameter("username", username); + sqlQuery.setParameter(AppConstants.USER_NAME, username); bookcount = (BigInteger) sqlQuery.uniqueResult(); } return bookcount; diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java index d2fa945b617d..b5e70f257ebb 100644 --- a/dao/src/main/java/com/iluwatar/dao/App.java +++ b/dao/src/main/java/com/iluwatar/dao/App.java @@ -52,6 +52,7 @@ public class App { private static final String DB_URL = "jdbc:h2:~/dao"; private static Logger log = Logger.getLogger(App.class); + private static final String ALL_CUSTOMERS = "customerDao.getAllCustomers(): "; /** * Program entry point. @@ -92,23 +93,23 @@ private static DataSource createDataSource() { private static void performOperationsUsing(final CustomerDao customerDao) throws Exception { addCustomers(customerDao); - log.info("customerDao.getAllCustomers(): "); + log.info(ALL_CUSTOMERS); try (Stream customerStream = customerDao.getAll()) { customerStream.forEach((customer) -> log.info(customer)); } log.info("customerDao.getCustomerById(2): " + customerDao.getById(2)); final Customer customer = new Customer(4, "Dan", "Danson"); customerDao.add(customer); - log.info("customerDao.getAllCustomers(): " + customerDao.getAll()); + log.info(ALL_CUSTOMERS + customerDao.getAll()); customer.setFirstName("Daniel"); customer.setLastName("Danielson"); customerDao.update(customer); - log.info("customerDao.getAllCustomers(): "); + log.info(ALL_CUSTOMERS); try (Stream customerStream = customerDao.getAll()) { customerStream.forEach((cust) -> log.info(cust)); } customerDao.delete(customer); - log.info("customerDao.getAllCustomers(): " + customerDao.getAll()); + log.info(ALL_CUSTOMERS + customerDao.getAll()); } private static void addCustomers(CustomerDao customerDao) throws Exception { 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 5fcd0d9ea04c..9a6cbcd058c4 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java @@ -36,6 +36,8 @@ public final class App { private static Logger log = Logger.getLogger(App.class); + private static final String STUDENT_STRING = "App.main(), student : "; + /** * Program entry point. @@ -53,12 +55,12 @@ public static void main(final String... args) { /* Add student in respectibe store */ mapper.insert(student); - log.debug("App.main(), student : " + student + ", is inserted"); + log.debug(STUDENT_STRING + student + ", is inserted"); /* Find this student */ final Optional studentToBeFound = mapper.find(student.getStudentId()); - log.debug("App.main(), student : " + studentToBeFound + ", is searched"); + log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); /* Update existing student object */ student = new Student(student.getStudentId(), "AdamUpdated", 'A'); @@ -66,8 +68,8 @@ public static void main(final String... args) { /* Update student in respectibe db */ mapper.update(student); - log.debug("App.main(), student : " + student + ", is updated"); - log.debug("App.main(), student : " + student + ", is going to be deleted"); + log.debug(STUDENT_STRING + student + ", is updated"); + log.debug(STUDENT_STRING + student + ", is going to be deleted"); /* Delete student in db */ mapper.delete(student); diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java index 311ffa0e11f8..b5832fe41cb2 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/Meteoroid.java @@ -25,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.iluwatar.doubledispatch.constants.AppConstants; + /** * * Meteoroid game object @@ -45,21 +47,21 @@ public void collision(GameObject gameObject) { @Override public void collisionResolve(FlamingAsteroid asteroid) { - LOGGER.info("{} hits {}.", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()); + LOGGER.info(AppConstants.HITS, asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()); } @Override public void collisionResolve(Meteoroid meteoroid) { - LOGGER.info("{} hits {}.", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()); + LOGGER.info(AppConstants.HITS, meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()); } @Override public void collisionResolve(SpaceStationMir mir) { - LOGGER.info("{} hits {}.", mir.getClass().getSimpleName(), this.getClass().getSimpleName()); + LOGGER.info(AppConstants.HITS, mir.getClass().getSimpleName(), this.getClass().getSimpleName()); } @Override public void collisionResolve(SpaceStationIss iss) { - LOGGER.info("{} hits {}.", iss.getClass().getSimpleName(), this.getClass().getSimpleName()); + LOGGER.info(AppConstants.HITS, iss.getClass().getSimpleName(), this.getClass().getSimpleName()); } } diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java index 419be2e30c78..e1183f9afee0 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/SpaceStationMir.java @@ -25,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.iluwatar.doubledispatch.constants.AppConstants; + /** * * Space station Mir game object @@ -45,7 +47,7 @@ public void collision(GameObject gameObject) { @Override public void collisionResolve(FlamingAsteroid asteroid) { - LOGGER.info("{} hits {}. {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(), + LOGGER.info(AppConstants.HITS," {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); setDamaged(true); setOnFire(true); @@ -53,21 +55,21 @@ public void collisionResolve(FlamingAsteroid asteroid) { @Override public void collisionResolve(Meteoroid meteoroid) { - LOGGER.info("{} hits {}. {} is damaged!", meteoroid.getClass().getSimpleName(), + LOGGER.info(AppConstants.HITS," {} is damaged!", meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); setDamaged(true); } @Override public void collisionResolve(SpaceStationMir mir) { - LOGGER.info("{} hits {}. {} is damaged!", mir.getClass().getSimpleName(), + LOGGER.info(AppConstants.HITS," {} is damaged!", mir.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); setDamaged(true); } @Override public void collisionResolve(SpaceStationIss iss) { - LOGGER.info("{} hits {}. {} is damaged!", iss.getClass().getSimpleName(), + LOGGER.info(AppConstants.HITS," {} is damaged!", iss.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); setDamaged(true); } diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java new file mode 100644 index 000000000000..7e25e67b558f --- /dev/null +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java @@ -0,0 +1,11 @@ +package com.iluwatar.doubledispatch.constants; + +/** + * + * Constants class to define all constants + * + */ +public class AppConstants { + + public static final String HITS = "{} hits {}."; +} From f7e22a1cf6f7664e8790cc5c76285adbcc6ab19d Mon Sep 17 00:00:00 2001 From: kanwarpreet25 <39183641+kanwarpreet25@users.noreply.github.com> Date: Sun, 28 Jul 2019 18:12:03 +0530 Subject: [PATCH 04/28] 508 : Sonar qube critical Issue Fix (#854) * 508 : Sonar qube critical Issue Fix Refactor this method to reduce its Cognitive Complexity from 30 to the 15 allowed. * 508: Sonar Qube Issue fxes Define a constant instead of duplicating this literal " does not exist." 3 times. * 508: sonar qube issue fixes Define a constant instead of duplicating this literal "Some external api for only realtime execution could be called here." 3 times. --- .../com/iluwatar/event/asynchronous/App.java | 111 ++++++++++-------- .../event/asynchronous/EventManager.java | 8 +- .../event/sourcing/domain/Account.java | 8 +- 3 files changed, 72 insertions(+), 55 deletions(-) diff --git a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/App.java b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/App.java index 6e9138d3c518..820279bc058a 100644 --- a/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/App.java +++ b/event-asynchronous/src/main/java/com/iluwatar/event/asynchronous/App.java @@ -60,7 +60,8 @@ public class App { /** * Program entry point. * - * @param args command line args + * @param args + * command line args */ public static void main(String[] args) { App app = new App(); @@ -150,56 +151,11 @@ public void runInteractiveMode() { option = s.nextInt(); if (option == 1) { - s.nextLine(); - LOGGER.info("Boil multiple eggs at once (A) or boil them one-by-one (S)?: "); - String eventType = s.nextLine(); - LOGGER.info("How long should this egg be boiled for (in seconds)?: "); - int eventTime = s.nextInt(); - if (eventType.equalsIgnoreCase("A")) { - try { - int eventId = eventManager.createAsync(eventTime); - eventManager.start(eventId); - LOGGER.info("Egg [{}] is being boiled.", eventId); - } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { - LOGGER.error(e.getMessage()); - } - } else if (eventType.equalsIgnoreCase("S")) { - try { - int eventId = eventManager.create(eventTime); - eventManager.start(eventId); - LOGGER.info("Egg [{}] is being boiled.", eventId); - } catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException - | EventDoesNotExistException e) { - LOGGER.error(e.getMessage()); - } - } else { - LOGGER.info("Unknown event type."); - } + processOption1(eventManager, s); } else if (option == 2) { - LOGGER.info("Which egg?: "); - int eventId = s.nextInt(); - try { - eventManager.cancel(eventId); - LOGGER.info("Egg [{}] is removed from boiler.", eventId); - } catch (EventDoesNotExistException e) { - LOGGER.error(e.getMessage()); - } + processOption2(eventManager, s); } else if (option == 3) { - s.nextLine(); - LOGGER.info("Just one egg (O) OR all of them (A) ?: "); - String eggChoice = s.nextLine(); - - if (eggChoice.equalsIgnoreCase("O")) { - LOGGER.info("Which egg?: "); - int eventId = s.nextInt(); - try { - eventManager.status(eventId); - } catch (EventDoesNotExistException e) { - LOGGER.error(e.getMessage()); - } - } else if (eggChoice.equalsIgnoreCase("A")) { - eventManager.statusOfAllEvents(); - } + processOption3(eventManager, s); } else if (option == 4) { eventManager.shutdown(); } @@ -208,4 +164,61 @@ public void runInteractiveMode() { s.close(); } + private void processOption3(EventManager eventManager, Scanner s) { + s.nextLine(); + LOGGER.info("Just one egg (O) OR all of them (A) ?: "); + String eggChoice = s.nextLine(); + + if (eggChoice.equalsIgnoreCase("O")) { + LOGGER.info("Which egg?: "); + int eventId = s.nextInt(); + try { + eventManager.status(eventId); + } catch (EventDoesNotExistException e) { + LOGGER.error(e.getMessage()); + } + } else if (eggChoice.equalsIgnoreCase("A")) { + eventManager.statusOfAllEvents(); + } + } + + private void processOption2(EventManager eventManager, Scanner s) { + LOGGER.info("Which egg?: "); + int eventId = s.nextInt(); + try { + eventManager.cancel(eventId); + LOGGER.info("Egg [{}] is removed from boiler.", eventId); + } catch (EventDoesNotExistException e) { + LOGGER.error(e.getMessage()); + } + } + + private void processOption1(EventManager eventManager, Scanner s) { + s.nextLine(); + LOGGER.info("Boil multiple eggs at once (A) or boil them one-by-one (S)?: "); + String eventType = s.nextLine(); + LOGGER.info("How long should this egg be boiled for (in seconds)?: "); + int eventTime = s.nextInt(); + if (eventType.equalsIgnoreCase("A")) { + try { + int eventId = eventManager.createAsync(eventTime); + eventManager.start(eventId); + LOGGER.info("Egg [{}] is being boiled.", eventId); + } catch (MaxNumOfEventsAllowedException | LongRunningEventException | EventDoesNotExistException e) { + LOGGER.error(e.getMessage()); + } + } else if (eventType.equalsIgnoreCase("S")) { + try { + int eventId = eventManager.create(eventTime); + eventManager.start(eventId); + LOGGER.info("Egg [{}] is being boiled.", eventId); + } catch (MaxNumOfEventsAllowedException | InvalidOperationException | LongRunningEventException + | EventDoesNotExistException e) { + LOGGER.error(e.getMessage()); + } + } else { + LOGGER.info("Unknown event type."); + } + } + } 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 729900620aa0..d54665bb21f5 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 @@ -39,6 +39,8 @@ public class EventManager implements ThreadCompleteListener { private int currentlyRunningSyncEvent = -1; private Random rand; private Map eventPool; + + private static final String DOES_NOT_EXIST = " does not exist."; /** * EventManager constructor. @@ -112,7 +114,7 @@ private int createEvent(int eventTime, boolean isSynchronous) */ public void start(int eventId) throws EventDoesNotExistException { if (!eventPool.containsKey(eventId)) { - throw new EventDoesNotExistException(eventId + " does not exist."); + throw new EventDoesNotExistException(eventId + DOES_NOT_EXIST); } eventPool.get(eventId).start(); @@ -126,7 +128,7 @@ public void start(int eventId) throws EventDoesNotExistException { */ public void cancel(int eventId) throws EventDoesNotExistException { if (!eventPool.containsKey(eventId)) { - throw new EventDoesNotExistException(eventId + " does not exist."); + throw new EventDoesNotExistException(eventId + DOES_NOT_EXIST); } if (eventId == currentlyRunningSyncEvent) { @@ -145,7 +147,7 @@ public void cancel(int eventId) throws EventDoesNotExistException { */ public void status(int eventId) throws EventDoesNotExistException { if (!eventPool.containsKey(eventId)) { - throw new EventDoesNotExistException(eventId + " does not exist."); + throw new EventDoesNotExistException(eventId + DOES_NOT_EXIST); } eventPool.get(eventId).status(); diff --git a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java index d2e5f429b5d4..a8ba649eb602 100644 --- a/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java +++ b/event-sourcing/src/main/java/com/iluwatar/event/sourcing/domain/Account.java @@ -44,6 +44,8 @@ public class Account { private final int accountNo; private final String owner; private BigDecimal money; + + private static final String MSG = "Some external api for only realtime execution could be called here."; /** * Instantiates a new Account. @@ -126,7 +128,7 @@ private void handleDeposit(BigDecimal money, boolean realTime) { depositMoney(money); AccountAggregate.putAccount(this); if (realTime) { - LOGGER.info("Some external api for only realtime execution could be called here."); + LOGGER.info(MSG); } } @@ -138,7 +140,7 @@ private void handleWithdrawal(BigDecimal money, boolean realTime) { withdrawMoney(money); AccountAggregate.putAccount(this); if (realTime) { - LOGGER.info("Some external api for only realtime execution could be called here."); + LOGGER.info(MSG); } } @@ -160,7 +162,7 @@ public void handleEvent(MoneyDepositEvent moneyDepositEvent) { public void handleEvent(AccountCreateEvent accountCreateEvent) { AccountAggregate.putAccount(this); if (accountCreateEvent.isRealTime()) { - LOGGER.info("Some external api for only realtime execution could be called here."); + LOGGER.info(MSG); } } From a113de6a14526e8d9f495f7d3af39b3da8cc81d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 28 Jul 2019 16:24:14 +0300 Subject: [PATCH 05/28] Add licenses --- .../domain/enums/Property.java | 22 +++++++++++++++++ .../caching/constants/CachingConstants.java | 22 +++++++++++++++++ .../iluwatar/cqrs/constants/AppConstants.java | 22 +++++++++++++++++ .../constants/AppConstants.java | 22 +++++++++++++++++ typeobjectpattern/pom.xml | 24 +++++++++++++++++++ 5 files changed, 112 insertions(+) diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java index b766141a87f2..c20f5b26de41 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/enums/Property.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.abstractdocument.domain.enums; /** diff --git a/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java b/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java index cc5e34e2d2b0..885829caf2e6 100644 --- a/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java +++ b/caching/src/main/java/com/iluwatar/caching/constants/CachingConstants.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.caching.constants; /** diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java b/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java index 154d63a892cf..07a8b96190b3 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/constants/AppConstants.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.cqrs.constants; /** diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java index 7e25e67b558f..29b7b58d8b98 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/constants/AppConstants.java @@ -1,3 +1,25 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package com.iluwatar.doubledispatch.constants; /** diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index 3377245f30ba..35d3b966194b 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -1,3 +1,27 @@ + 4.0.0 From d9a567cf970748ea8109ef99013393f88821ff05 Mon Sep 17 00:00:00 2001 From: AnaghaSasikumar <42939261+AnaghaSasikumar@users.noreply.github.com> Date: Mon, 29 Jul 2019 23:39:08 +0530 Subject: [PATCH 06/28] Commander pattern #505 (#857) * Commander pattern * Fix checkstyle errors * Update Commander.java * Update README.md * Update PaymentService.java * Update Commander.java * Update README.md --- commander/README.md | 24 + commander/pom.xml | 26 + commander/properties/log4j.properties | 18 + .../commander/AppEmployeeDbFailCases.java | 96 +++ .../commander/AppMessagingFailCases.java | 138 ++++ .../commander/AppPaymentFailCases.java | 109 ++++ .../iluwatar/commander/AppQueueFailCases.java | 136 ++++ .../commander/AppShippingFailCases.java | 123 ++++ .../com/iluwatar/commander/Commander.java | 613 ++++++++++++++++++ .../java/com/iluwatar/commander/Database.java | 37 ++ .../java/com/iluwatar/commander/Order.java | 82 +++ .../java/com/iluwatar/commander/Retry.java | 105 +++ .../java/com/iluwatar/commander/Service.java | 72 ++ .../java/com/iluwatar/commander/User.java | 39 ++ .../employeehandle/EmployeeDatabase.java | 51 ++ .../employeehandle/EmployeeHandle.java | 54 ++ .../DatabaseUnavailableException.java | 33 + .../exceptions/IsEmptyException.java | 32 + .../exceptions/ItemUnavailableException.java | 32 + .../PaymentDetailsErrorException.java | 33 + .../ShippingNotPossibleException.java | 33 + .../messagingservice/MessagingDatabase.java | 52 ++ .../messagingservice/MessagingService.java | 95 +++ .../paymentservice/PaymentDatabase.java | 55 ++ .../paymentservice/PaymentService.java | 72 ++ .../com/iluwatar/commander/queue/Queue.java | 97 +++ .../commander/queue/QueueDatabase.java | 82 +++ .../iluwatar/commander/queue/QueueTask.java | 82 +++ .../shippingservice/ShippingDatabase.java | 52 ++ .../shippingservice/ShippingService.java | 70 ++ .../com/iluwatar/commander/RetryTest.java | 76 +++ pom.xml | 1 + 32 files changed, 2620 insertions(+) create mode 100644 commander/README.md create mode 100644 commander/pom.xml create mode 100644 commander/properties/log4j.properties create mode 100644 commander/src/main/java/com/iluwatar/commander/AppEmployeeDbFailCases.java create mode 100644 commander/src/main/java/com/iluwatar/commander/AppMessagingFailCases.java create mode 100644 commander/src/main/java/com/iluwatar/commander/AppPaymentFailCases.java create mode 100644 commander/src/main/java/com/iluwatar/commander/AppQueueFailCases.java create mode 100644 commander/src/main/java/com/iluwatar/commander/AppShippingFailCases.java create mode 100644 commander/src/main/java/com/iluwatar/commander/Commander.java create mode 100644 commander/src/main/java/com/iluwatar/commander/Database.java create mode 100644 commander/src/main/java/com/iluwatar/commander/Order.java create mode 100644 commander/src/main/java/com/iluwatar/commander/Retry.java create mode 100644 commander/src/main/java/com/iluwatar/commander/Service.java create mode 100644 commander/src/main/java/com/iluwatar/commander/User.java create mode 100644 commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java create mode 100644 commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeHandle.java create mode 100644 commander/src/main/java/com/iluwatar/commander/exceptions/DatabaseUnavailableException.java create mode 100644 commander/src/main/java/com/iluwatar/commander/exceptions/IsEmptyException.java create mode 100644 commander/src/main/java/com/iluwatar/commander/exceptions/ItemUnavailableException.java create mode 100644 commander/src/main/java/com/iluwatar/commander/exceptions/PaymentDetailsErrorException.java create mode 100644 commander/src/main/java/com/iluwatar/commander/exceptions/ShippingNotPossibleException.java create mode 100644 commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java create mode 100644 commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java create mode 100644 commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java create mode 100644 commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentService.java create mode 100644 commander/src/main/java/com/iluwatar/commander/queue/Queue.java create mode 100644 commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java create mode 100644 commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java create mode 100644 commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java create mode 100644 commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingService.java create mode 100644 commander/src/test/java/com/iluwatar/commander/RetryTest.java diff --git a/commander/README.md b/commander/README.md new file mode 100644 index 000000000000..41e2cd587553 --- /dev/null +++ b/commander/README.md @@ -0,0 +1,24 @@ +--- +layout: pattern +title: Commander +folder: commander +permalink: /patterns/commander/ +categories: +tags: + - Java + - Difficulty-Intermediate +--- + +## Intent + +> Used to handle all problems that can be encountered when doing distributed transactions. + +## Applicability +This pattern can be used when we need to make commits into 2 (or more) databases to complete transaction, which cannot be done atomically and can thereby create problems. + +## Explanation +Handling distributed transactions can be tricky, but if we choose to not handle it carefully, there could be unwanted consequences. Say, we have an e-commerce website which has a Payment microservice and a Shipping microservice. If the shipping is available currently but payment service is not up, or vice versa, how would we deal with it after having already received the order from the user? +We need a mechanism in place which can handle these kinds of situations. We have to direct the order to either one of the services (in this example, shipping) and then add the order into the database of the other service (in this example, payment), since two databses cannot be updated atomically. If currently unable to do it, there should be a queue where this request can be queued, and there has to be a mechanism which allows for a failure in the queueing as well. All this needs to be done by constant retries while ensuring idempotence (even if the request is made several times, the change should only be applied once) by a commander class, to reach a state of eventual consistency. + +## Credits +* [https://www.grahamlea.com/2016/08/distributed-transactions-microservices-icebergs/] diff --git a/commander/pom.xml b/commander/pom.xml new file mode 100644 index 000000000000..895906e65ded --- /dev/null +++ b/commander/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.21.0-SNAPSHOT + + commander + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + log4j + log4j + 1.2.17 + + + \ No newline at end of file diff --git a/commander/properties/log4j.properties b/commander/properties/log4j.properties new file mode 100644 index 000000000000..d7a52f503e83 --- /dev/null +++ b/commander/properties/log4j.properties @@ -0,0 +1,18 @@ +#Define root logger options +log4j.rootLogger=TRACE, file, console + +#Define console appender +log4j.appender.console=org.apache.log4j.ConsoleAppender +logrj.appender.console.Target=System.out +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd} %d{HH:mm:ss} %5p[%t] %m%n + +#Define rolling file appender +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=/log/logFile.log +log4j.appender.file.Append=true +log4j.appender.file.ImmediateFlush=true +log4j.appender.file.MaxFileSize=10MB +log4j.appender.file.MaxBackupIndex=5 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d %d{HH:mm:ss} %5p[%t] %m%n diff --git a/commander/src/main/java/com/iluwatar/commander/AppEmployeeDbFailCases.java b/commander/src/main/java/com/iluwatar/commander/AppEmployeeDbFailCases.java new file mode 100644 index 000000000000..d0975b2b5b7f --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/AppEmployeeDbFailCases.java @@ -0,0 +1,96 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.employeehandle.EmployeeDatabase; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.ItemUnavailableException; +import com.iluwatar.commander.messagingservice.MessagingDatabase; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.paymentservice.PaymentDatabase; +import com.iluwatar.commander.paymentservice.PaymentService; +import com.iluwatar.commander.shippingservice.ShippingDatabase; +import com.iluwatar.commander.shippingservice.ShippingService; +import com.iluwatar.commander.queue.QueueDatabase; + +/** + * AppEmployeeDbFailCases class looks at possible cases when Employee handle service is + * available/unavailable. + */ + +public class AppEmployeeDbFailCases { + final int numOfRetries = 3; + final long retryDuration = 30000; + final long queueTime = 240000; //4 mins + final long queueTaskTime = 60000; //1 min + final long paymentTime = 120000; //2 mins + final long messageTime = 150000; //2.5 mins + final long employeeTime = 240000; //4 mins + + void employeeDatabaseUnavailableCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void employeeDbSuccessCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + /** + * Program entry point. + * + * @param args command line args + */ + + public static void main(String[] args) throws Exception { + AppEmployeeDbFailCases aefc = new AppEmployeeDbFailCases(); + //aefc.employeeDatabaseUnavailableCase(); + aefc.employeeDbSuccessCase(); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/AppMessagingFailCases.java b/commander/src/main/java/com/iluwatar/commander/AppMessagingFailCases.java new file mode 100644 index 000000000000..5b5717d2e5c6 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/AppMessagingFailCases.java @@ -0,0 +1,138 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.employeehandle.EmployeeDatabase; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.messagingservice.MessagingDatabase; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.paymentservice.PaymentDatabase; +import com.iluwatar.commander.paymentservice.PaymentService; +import com.iluwatar.commander.shippingservice.ShippingDatabase; +import com.iluwatar.commander.shippingservice.ShippingService; +import com.iluwatar.commander.queue.QueueDatabase; + +/** + * AppMessagingFailCases class looks at possible cases when Messaging service is + * available/unavailable. + */ + +public class AppMessagingFailCases { + final int numOfRetries = 3; + final long retryDuration = 30000; + final long queueTime = 240000; //4 mins + final long queueTaskTime = 60000; //1 min + final long paymentTime = 120000; //2 mins + final long messageTime = 150000; //2.5 mins + final long employeeTime = 240000; //4 mins + + void messagingDatabaseUnavailableCasePaymentSuccess() throws Exception { + //rest is successful + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void messagingDatabaseUnavailableCasePaymentError() throws Exception { + //rest is successful + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void messagingDatabaseUnavailableCasePaymentFailure() throws Exception { + //rest is successful + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration,queueTime,queueTaskTime, + paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void messagingSuccessCase() throws Exception { + //done here + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + /** + * Program entry point. + * + * @param args command line args + */ + + public static void main(String[] args) throws Exception { + AppMessagingFailCases amfc = new AppMessagingFailCases(); + //amfc.messagingDatabaseUnavailableCasePaymentSuccess(); + //amfc.messagingDatabaseUnavailableCasePaymentError(); + //amfc.messagingDatabaseUnavailableCasePaymentFailure(); + amfc.messagingSuccessCase(); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/AppPaymentFailCases.java b/commander/src/main/java/com/iluwatar/commander/AppPaymentFailCases.java new file mode 100644 index 000000000000..ca67571abe2c --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/AppPaymentFailCases.java @@ -0,0 +1,109 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.employeehandle.EmployeeDatabase; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.PaymentDetailsErrorException; +import com.iluwatar.commander.messagingservice.MessagingDatabase; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.paymentservice.PaymentDatabase; +import com.iluwatar.commander.paymentservice.PaymentService; +import com.iluwatar.commander.shippingservice.ShippingDatabase; +import com.iluwatar.commander.shippingservice.ShippingService; +import com.iluwatar.commander.queue.QueueDatabase; + +/** + * AppPaymentFailCases class looks at possible cases when Payment service is + * available/unavailable. + */ + +public class AppPaymentFailCases { + final int numOfRetries = 3; + final long retryDuration = 30000; + final long queueTime = 240000; //4 mins + final long queueTaskTime = 60000; //1 min + final long paymentTime = 120000; //2 mins + final long messageTime = 150000; //2.5 mins + final long employeeTime = 240000; //4 mins + + void paymentNotPossibleCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new PaymentDetailsErrorException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void paymentDatabaseUnavailableCase() throws Exception { + //rest is successful + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void paymentSuccessCase() throws Exception { + //goes to message after 2 retries maybe - rest is successful for now + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + /** + * Program entry point. + * + * @param args command line args + */ + + public static void main(String[] args) throws Exception { + AppPaymentFailCases apfc = new AppPaymentFailCases(); + //apfc.paymentNotPossibleCase(); + //apfc.paymentDatabaseUnavailableCase(); + apfc.paymentSuccessCase(); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/AppQueueFailCases.java b/commander/src/main/java/com/iluwatar/commander/AppQueueFailCases.java new file mode 100644 index 000000000000..de9f90dab7a3 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/AppQueueFailCases.java @@ -0,0 +1,136 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.employeehandle.EmployeeDatabase; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.ItemUnavailableException; +import com.iluwatar.commander.messagingservice.MessagingDatabase; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.paymentservice.PaymentDatabase; +import com.iluwatar.commander.paymentservice.PaymentService; +import com.iluwatar.commander.shippingservice.ShippingDatabase; +import com.iluwatar.commander.shippingservice.ShippingService; +import com.iluwatar.commander.queue.QueueDatabase; + +/** + * AppQueueFailCases class looks at possible cases when Queue Database is + * available/unavailable. + */ + +public class AppQueueFailCases { + final int numOfRetries = 3; + final long retryDuration = 30000; + final long queueTime = 240000; //4 mins + final long queueTaskTime = 60000; //1 min + final long paymentTime = 120000; //2 mins + final long messageTime = 150000; //2.5 mins + final long employeeTime = 240000; //4 mins + + void queuePaymentTaskDatabaseUnavailableCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void queueMessageTaskDatabaseUnavailableCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void queueEmployeeDbTaskDatabaseUnavailableCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void queueSuccessCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(new DatabaseUnavailableException(), new DatabaseUnavailableException()); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + /** + * Program entry point. + * + * @param args command line args + */ + + public static void main(String[] args) throws Exception { + AppQueueFailCases aqfc = new AppQueueFailCases(); + //aqfc.queuePaymentTaskDatabaseUnavailableCase(); + //aqfc.queueMessageTaskDatabaseUnavailableCase(); + //aqfc.queueEmployeeDbTaskDatabaseUnavailableCase(); + aqfc.queueSuccessCase(); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/AppShippingFailCases.java b/commander/src/main/java/com/iluwatar/commander/AppShippingFailCases.java new file mode 100644 index 000000000000..6245d9865e59 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/AppShippingFailCases.java @@ -0,0 +1,123 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.employeehandle.EmployeeDatabase; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.ItemUnavailableException; +import com.iluwatar.commander.exceptions.ShippingNotPossibleException; +import com.iluwatar.commander.messagingservice.MessagingDatabase; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.paymentservice.PaymentDatabase; +import com.iluwatar.commander.paymentservice.PaymentService; +import com.iluwatar.commander.shippingservice.ShippingDatabase; +import com.iluwatar.commander.shippingservice.ShippingService; +import com.iluwatar.commander.queue.QueueDatabase; + +/** + * AppShippingFailCases class looks at possible cases when Shipping service is + * available/unavailable. + */ + +public class AppShippingFailCases { + final int numOfRetries = 3; + final long retryDuration = 30000; + final long queueTime = 240000; //4 mins + final long queueTaskTime = 60000; //1 min + final long paymentTime = 120000; //2 mins + final long messageTime = 150000; //2.5 mins + final long employeeTime = 240000; //4 mins + + void itemUnavailableCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new ItemUnavailableException()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void shippingNotPossibleCase() throws Exception { + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new ShippingNotPossibleException()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void shippingDatabaseUnavailableCase() throws Exception { + //rest is successful + PaymentService ps = new PaymentService(new PaymentDatabase()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException(), new DatabaseUnavailableException(), + new DatabaseUnavailableException(), new DatabaseUnavailableException()); + MessagingService ms = new MessagingService(new MessagingDatabase()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + void shippingSuccessCase() throws Exception { + //goes to payment after 2 retries maybe - rest is successful for now + PaymentService ps = new PaymentService(new PaymentDatabase(), new DatabaseUnavailableException()); + ShippingService ss = new ShippingService(new ShippingDatabase(), new DatabaseUnavailableException(), + new DatabaseUnavailableException()); + MessagingService ms = new MessagingService(new MessagingDatabase(), new DatabaseUnavailableException()); + EmployeeHandle eh = new EmployeeHandle(new EmployeeDatabase()); + QueueDatabase qdb = new QueueDatabase(); + Commander c = new Commander(eh,ps,ss,ms,qdb,numOfRetries,retryDuration, + queueTime,queueTaskTime,paymentTime,messageTime,employeeTime); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + c.placeOrder(order); + } + + /** + * Program entry point. + * + * @param args command line args + */ + + public static void main(String[] args) throws Exception { + AppShippingFailCases asfc = new AppShippingFailCases(); + //asfc.itemUnavailableCase(); + //asfc.shippingNotPossibleCase(); + //asfc.shippingDatabaseUnavailableCase(); + asfc.shippingSuccessCase(); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/Commander.java b/commander/src/main/java/com/iluwatar/commander/Commander.java new file mode 100644 index 000000000000..87d4604d4ac3 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/Commander.java @@ -0,0 +1,613 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import java.util.ArrayList; +import org.apache.log4j.Logger; +import com.iluwatar.commander.employeehandle.EmployeeHandle; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.ItemUnavailableException; +import com.iluwatar.commander.exceptions.PaymentDetailsErrorException; +import com.iluwatar.commander.exceptions.ShippingNotPossibleException; +import com.iluwatar.commander.messagingservice.MessagingService; +import com.iluwatar.commander.Order.MessageSent; +import com.iluwatar.commander.Order.PaymentStatus; +import com.iluwatar.commander.paymentservice.PaymentService; +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; + +/** + *

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 instructions and ensures proper completion using retries and + * taking care of idempotence. By queueing instructions while they haven't been done, + * we can ensure a state of 'eventual consistency'.

+ *

In our example, we have an e-commerce application. When the user places an order, + * the shipping service is intimated first. If the service does not respond for some + * reason, the order is not placed. If response is received, the commander then calls + * for the payment service to be intimated. If this fails, the shipping still takes + * place (order converted to COD) and the item is queued. If the queue is also found + * to be unavailable, the payment is noted to be not done and this is added to an + * employee database. Three types of messages are sent to the user - one, if payment + * succeeds; two, if payment fails definitively; and three, if payment fails in the + * first attempt. If the message is not sent, this is also queued and is added to employee + * db. We also have a time limit for each instruction to be completed, after which, the + * instruction is not executed, thereby ensuring that resources are not held for too long. + * In the rare occasion in which everything fails, an individual would have to step in to + * figure out how to solve the issue.

+ *

We have abstract classes {@link Database} and {@link Service} which are extended + * by all the databases and services. Each service has a database to be updated, and + * receives request from an outside user (the {@link Commander} class here). There are + * 5 microservices - {@link ShippingService}, {@link PaymentService}, {@link MessagingService}, + * {@link EmployeeHandle} and a {@link QueueDatabase}. We use retries to execute any + * instruction using {@link Retry} class, and idempotence is ensured by going through some + * checks before making requests to services and making change in {@link Order} class fields + * if request succeeds or definitively fails. There are 5 classes - + * {@link AppShippingFailCases}, {@link AppPaymentFailCases}, {@link AppMessagingFailCases}, + * {@link AppQueueFailCases} and {@link AppEmployeeDbFailCases}, which look at the different + * scenarios that may be encountered during the placing of an order.

+ */ + +public class Commander { + + private final QueueDatabase queue; + private final EmployeeHandle employeeDb; + private final PaymentService paymentService; + private final ShippingService shippingService; + private final MessagingService messagingService; + private int queueItems = 0; //keeping track here only so don't need access to queue db to get this + private final int numOfRetries; + private final long retryDuration; + private final long queueTime; + private final long queueTaskTime; + private final long paymentTime; + private final long messageTime; + private final long employeeTime; + private boolean finalSiteMsgShown; + static final Logger LOG = Logger.getLogger(Commander.class); + //we could also have another db where it stores all orders + + Commander(EmployeeHandle empDb, PaymentService pService, ShippingService sService, + MessagingService mService, QueueDatabase qdb, int numOfRetries, long retryDuration, + long queueTime, long queueTaskTime, long paymentTime, long messageTime, long employeeTime) { + this.paymentService = pService; + this.shippingService = sService; + this.messagingService = mService; + this.employeeDb = empDb; + this.queue = qdb; + this.numOfRetries = numOfRetries; + this.retryDuration = retryDuration; + this.queueTime = queueTime; + this.queueTaskTime = queueTaskTime; + this.paymentTime = paymentTime; + this.messageTime = messageTime; + this.employeeTime = employeeTime; + this.finalSiteMsgShown = false; + } + + void placeOrder(Order order) throws Exception { + sendShippingRequest(order); + } + + private void sendShippingRequest(Order order) throws Exception { + ArrayList list = shippingService.exceptionsList; + Retry.Operation op = (l) -> { + if (!l.isEmpty()) { + if (DatabaseUnavailableException.class.isAssignableFrom(l.get(0).getClass())) { + LOG.debug("Order " + order.id + ": Error in connecting to shipping service, trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating shipping request.."); + } + throw l.remove(0); + } + String transactionId = shippingService.receiveRequest(order.item, order.user.address); + //could save this transaction id in a db too + LOG.info("Order " + order.id + ": Shipping placed successfully, transaction id: " + transactionId); + System.out.println("Order has been placed and will be shipped to you. Please wait while we make your" + + " payment... "); + sendPaymentRequest(order); + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + if (ShippingNotPossibleException.class.isAssignableFrom(err.getClass())) { + System.out.println("Shipping is currently not possible to your address. We are working on the problem " + + "and will get back to you asap."); + finalSiteMsgShown = true; + LOG.info("Order " + order.id + ": Shipping not possible to address, trying to add problem to employee db.."); + employeeHandleIssue(o); + } else if (ItemUnavailableException.class.isAssignableFrom(err.getClass())) { + System.out.println("This item is currently unavailable. We will inform you as soon as the item becomes " + + "available again."); + finalSiteMsgShown = true; + LOG.info("Order " + order.id + ": Item " + order.item + " unavailable, trying to add problem to employee " + + "handle.."); + employeeHandleIssue(o); + } else { + System.out.println("Sorry, there was a problem in creating your order. Please try later."); + LOG.error("Order " + order.id + ": Shipping service unavailable, order not placed.."); + finalSiteMsgShown = true; + } + return; + }; + Retry r = new Retry(op, handleError, numOfRetries, retryDuration, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + r.perform(list, order); + } + + private void sendPaymentRequest(Order order) { + if (System.currentTimeMillis() - order.createdTime >= this.paymentTime) { + if (order.paid.equals(PaymentStatus.Trying)) { + order.paid = PaymentStatus.NotDone; + 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 + return; + } + ArrayList list = paymentService.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + 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)) { + String transactionId = paymentService.receiveRequest(order.price); + order.paid = PaymentStatus.Done; + LOG.info("Order " + order.id + ": Payment successful, transaction Id: " + transactionId); + if (!finalSiteMsgShown) { + System.out.println("Payment made successfully, thank you for shopping with us!!"); + finalSiteMsgShown = true; + } + sendSuccessMessage(order); + return; + } + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + if (PaymentDetailsErrorException.class.isAssignableFrom(err.getClass())) { + if (!finalSiteMsgShown) { + System.out.println("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 { + try { + if (o.messageSent.equals(MessageSent.NoneSent)) { + if (!finalSiteMsgShown) { + System.out.println("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) { + QueueTask qt = new QueueTask(o, TaskType.Payment,-1); + updateQueue(qt); + } + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + return; + }; + Retry 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 updateQueue(QueueTask qt) throws InterruptedException { + 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)) { + LOG.trace("Order " + qt.order.id + ": Not queueing task since task already done.."); + return; + } + ArrayList list = queue.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + Retry.Operation op = (list) -> { + if (!list.isEmpty()) { + LOG.warn("Order " + qt.order.id + ": Error in connecting to queue db, trying again.."); + throw list.remove(0); + } + queue.add(qt); + queueItems++; + LOG.info("Order " + qt.order.id + ": " + qt.getType() + " task enqueued.."); + tryDoingTasksInQueue(); + return; + }; + Retry.HandleErrorIssue handleError = (qt,err) -> { + if (qt.taskType.equals(TaskType.Payment)) { + qt.order.paid = PaymentStatus.NotDone; + sendPaymentFailureMessage(qt.order); + LOG.error("Order " + qt.order.id + ": Unable to enqueue payment task, payment failed.."); + } + LOG.error("Order " + qt.order.id + ": Unable to enqueue task of type " + qt.getType() + + ", trying to add to employee handle.."); + employeeHandleIssue(qt.order); + return; + }; + Retry r = new Retry(op, handleError, numOfRetries, retryDuration, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + try { + r.perform(list, qt); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + }); + t.start(); + } + + private void tryDoingTasksInQueue() { //commander controls operations done to queue + ArrayList list = queue.exceptionsList; + Thread t2 = new Thread(new Runnable() { + @Override + public void run() { + Retry.Operation op = (list) -> { + if (!list.isEmpty()) { + LOG.warn("Error in accessing queue db to do tasks, trying again.."); + throw list.remove(0); + } + doTasksInQueue(); + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + return; + }; + Retry r = new Retry(op, handleError, numOfRetries, retryDuration, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + try { + r.perform(list, null); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + }); + t2.start(); + } + + private void tryDequeue() { + ArrayList list = queue.exceptionsList; + Thread t3 = new Thread(new Runnable() { + @Override + public void run() { + Retry.Operation op = (list) -> { + if (!list.isEmpty()) { + LOG.warn("Error in accessing queue db to dequeue task, trying again.."); + throw list.remove(0); + } + queue.dequeue(); + queueItems--; + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + return; + }; + Retry r = new Retry(op, handleError, numOfRetries, retryDuration, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + try { + r.perform(list, null); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + }); + t3.start(); + } + + private void sendSuccessMessage(Order order) { + if (System.currentTimeMillis() - order.createdTime >= this.messageTime) { + LOG.trace("Order " + order.id + ": Message time for order over, returning.."); + return; + } + ArrayList list = messagingService.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + 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 Success msg), trying again.."); + } else { + LOG.debug("Order " + order.id + ": Error in creating Payment Success messaging request.."); + } + throw l.remove(0); + } + if (!order.messageSent.equals(MessageSent.PaymentFail) + && !order.messageSent.equals(MessageSent.PaymentSuccessful)) { + String requestId = messagingService.receiveRequest(2); + order.messageSent = MessageSent.PaymentSuccessful; + LOG.info("Order " + order.id + ": Payment Success message sent, request Id: " + requestId); + } + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + try { + if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent.equals(MessageSent.PaymentTrying)) + && System.currentTimeMillis() - o.createdTime < messageTime) { + QueueTask 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); + } + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + return; + }; + Retry 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) { + if (System.currentTimeMillis() - order.createdTime >= this.messageTime) { + LOG.trace("Order " + order.id + ": Message time for order over, returning.."); + return; + } + ArrayList list = messagingService.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + 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)) { + String requestId = messagingService.receiveRequest(0); + order.messageSent = MessageSent.PaymentFail; + LOG.info("Order " + order.id + ": Payment Failure message sent successfully, request Id: " + requestId); + } + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + if ((o.messageSent.equals(MessageSent.NoneSent) || o.messageSent.equals(MessageSent.PaymentTrying)) + && System.currentTimeMillis() - o.createdTime < messageTime) { + try { + QueueTask 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); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + return; + } + }; + Retry 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 sendPaymentPossibleErrorMsg(Order order) { + if (System.currentTimeMillis() - order.createdTime >= this.messageTime) { + LOG.trace("Message time for order over, returning.."); + return; + } + ArrayList list = messagingService.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + 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)) { + String requestId = messagingService.receiveRequest(1); + order.messageSent = MessageSent.PaymentTrying; + LOG.info("Order " + order.id + ": Payment Error message sent successfully, request Id: " + requestId); + } + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + try { + if (o.messageSent.equals(MessageSent.NoneSent) && order.paid.equals(PaymentStatus.Trying) + && System.currentTimeMillis() - o.createdTime < messageTime) { + QueueTask 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); + } + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + return; + }; + Retry 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 employeeHandleIssue(Order order) { + if (System.currentTimeMillis() - order.createdTime >= this.employeeTime) { + LOG.trace("Order " + order.id + ": Employee handle time for order over, returning.."); + return; + } + ArrayList list = employeeDb.exceptionsList; + Thread t = new Thread(new Runnable() { + @Override + public void run() { + Retry.Operation op = (l) -> { + if (!l.isEmpty()) { + LOG.warn("Order " + order.id + ": Error in connecting to employee handle, trying again.."); + throw l.remove(0); + } + if (!order.addedToEmployeeHandle) { + employeeDb.receiveRequest(order); + order.addedToEmployeeHandle = true; + LOG.info("Order " + order.id + ": Added order to employee database"); + } + return; + }; + Retry.HandleErrorIssue handleError = (o,err) -> { + try { + if (!o.addedToEmployeeHandle && System.currentTimeMillis() - order.createdTime < employeeTime) { + QueueTask qt = new QueueTask(order, TaskType.EmployeeDb,-1); + updateQueue(qt); + LOG.warn("Order " + order.id + ": Error in adding to employee db, trying to queue task.."); + return; + } + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + return; + }; + Retry 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 doTasksInQueue() throws Exception { + if (queueItems != 0) { + QueueTask qt = queue.peek(); //this should probably be cloned here + //this is why we have retry for doTasksInQueue + LOG.trace("Order " + qt.order.id + ": Started doing task of type " + qt.getType()); + if (qt.firstAttemptTime == -1) { + qt.firstAttemptTime = System.currentTimeMillis(); + } + if (System.currentTimeMillis() - qt.firstAttemptTime >= queueTaskTime) { + tryDequeue(); + 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)) { + 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)) { + 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)))) { + tryDequeue(); + LOG.trace("Order " + qt.order.id + ": This messaging task does not need to be done, dequeue.."); + } else if (qt.messageType == 0) { + sendPaymentFailureMessage(qt.order); + LOG.debug("Order " + qt.order.id + ": Trying to connect to messaging service.."); + } else if (qt.messageType == 1) { + sendPaymentPossibleErrorMsg(qt.order); + LOG.debug("Order " + qt.order.id + ": Trying to connect to messaging service.."); + } else if (qt.messageType == 2) { + sendSuccessMessage(qt.order); + LOG.debug("Order " + qt.order.id + ": Trying to connect to messaging service.."); + } + } else if (qt.taskType.equals(TaskType.EmployeeDb)) { + if (qt.order.addedToEmployeeHandle) { + tryDequeue(); + LOG.trace("Order " + qt.order.id + ": This employee handle task already done, dequeue.."); + } else { + employeeHandleIssue(qt.order); + LOG.debug("Order " + qt.order.id + ": Trying to connect to employee handle.."); + } + } + } + } + if (queueItems == 0) { + LOG.trace("Queue is empty, returning.."); + } else { + Thread.sleep(queueTaskTime / 3); + tryDoingTasksInQueue(); + } + return; + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/Database.java b/commander/src/main/java/com/iluwatar/commander/Database.java new file mode 100644 index 000000000000..09d145688aa7 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/Database.java @@ -0,0 +1,37 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * Database abstract class is extended by all databases in our example. The add and get + * methods are used by the respective service to add to database or get from database. + * @param T is the type of object being held by database. + */ + +public abstract class Database { + public abstract T add(T obj) throws DatabaseUnavailableException; + public abstract T get(String tId) throws DatabaseUnavailableException; +} diff --git a/commander/src/main/java/com/iluwatar/commander/Order.java b/commander/src/main/java/com/iluwatar/commander/Order.java new file mode 100644 index 000000000000..5ee787d612b7 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/Order.java @@ -0,0 +1,82 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import java.util.Hashtable; +import java.util.Random; + +/** + * Order class holds details of the order. + */ + +public class Order { //can store all transactions ids also + + enum PaymentStatus { + NotDone, Trying, Done + }; + + enum MessageSent { + NoneSent, PaymentFail, PaymentTrying, PaymentSuccessful + }; + + final User user; + final String item; + public final String id; + final float price; + final long createdTime; + private static final String ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + private static final Hashtable USED_IDS = new Hashtable(); + PaymentStatus paid; + MessageSent messageSent; //to avoid sending error msg on page and text more than once + boolean addedToEmployeeHandle; //to avoid creating more to enqueue + + Order(User user, String item, float price) { + this.createdTime = System.currentTimeMillis(); + this.user = user; + this.item = item; + this.price = price; + String id = createUniqueId(); + if (USED_IDS.get(id) != null) { + while (USED_IDS.get(id)) { + id = createUniqueId(); + } + } + this.id = id; + USED_IDS.put(this.id, true); + this.paid = PaymentStatus.Trying; + this.messageSent = MessageSent.NoneSent; + this.addedToEmployeeHandle = false; + } + + String createUniqueId() { + StringBuilder random = new StringBuilder(); + Random rand = new Random(); + while (random.length() < 12) { // length of the random string. + int index = (int) (rand.nextFloat() * ALL_CHARS.length()); + random.append(ALL_CHARS.charAt(index)); + } + return random.toString(); + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/Retry.java b/commander/src/main/java/com/iluwatar/commander/Retry.java new file mode 100644 index 000000000000..eefff663146f --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/Retry.java @@ -0,0 +1,105 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; + +/** + * Retry pattern + * @param is the type of object passed into HandleErrorIssue as a parameter. + */ + +public class Retry { + + /** + * Operation Interface will define method to be implemented. + */ + + public interface Operation { + void operation(ArrayList list) throws Exception; + } + + /** + * HandleErrorIssue defines how to handle errors. + * @param is the type of object to be passed into the method as parameter. + */ + + public interface HandleErrorIssue { + void handleIssue(T obj, Exception e); + } + + private final Operation op; + private final HandleErrorIssue handleError; + private final int maxAttempts; + private final long maxDelay; + private final AtomicInteger attempts; + private final Predicate test; + private final ArrayList errors; + + Retry(Operation op, HandleErrorIssue handleError, int maxAttempts, + long maxDelay, Predicate... ignoreTests) { + this.op = op; + this.handleError = handleError; + this.maxAttempts = maxAttempts; + this.maxDelay = maxDelay; + this.attempts = new AtomicInteger(); + this.test = Arrays.stream(ignoreTests).reduce(Predicate::or).orElse(e -> false); + this.errors = new ArrayList<>(); + } + + /** + * Performing the operation with retries. + * @param list is the exception list + * @param obj is the parameter to be passed into handleIsuue method + */ + + public void perform(ArrayList list, T obj) throws Exception { + do { + try { + op.operation(list); + return; + } catch (Exception e) { + this.errors.add(e); + if (this.attempts.incrementAndGet() >= this.maxAttempts || !this.test.test(e)) { + this.handleError.handleIssue(obj, e); + return; //return here...dont go further + } + try { + Random rand = new Random(); + long testDelay = (long) Math.pow(2, this.attempts.intValue()) * 1000 + rand.nextInt(1000); + long delay = testDelay < this.maxDelay ? testDelay : maxDelay; + Thread.sleep(delay); + } catch (InterruptedException f) { + //ignore + } + } + } + while (true); + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/Service.java b/commander/src/main/java/com/iluwatar/commander/Service.java new file mode 100644 index 000000000000..226f519eb046 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/Service.java @@ -0,0 +1,72 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Hashtable; +import java.util.Random; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * Service class is an abstract class extended by all services in this example. They + * all have a public receiveRequest method to receive requests, which could also contain + * details of the user other than the implementation details (though we are not doing + * that here) and updateDb method which adds to their respective databases. There is a + * method to generate transaction/request id for the transactions/requests, which are + * then sent back. These could be stored by the {@link Commander} class in a separate + * database for reference (though we are not doing that here). + */ + +public abstract class Service { + + protected final Database database; + public ArrayList exceptionsList; + private static final String ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + private static final Hashtable USED_IDS = new Hashtable(); + + protected Service(Database db, Exception...exc) { + this.database = db; + this.exceptionsList = new ArrayList(Arrays.asList(exc)); + } + + public abstract String receiveRequest(Object...parameters) throws DatabaseUnavailableException; + protected abstract String updateDb(Object...parameters) throws DatabaseUnavailableException; + + protected String generateId() { + StringBuilder random = new StringBuilder(); + Random rand = new Random(); + while (random.length() < 12) { // length of the random string. + int index = (int) (rand.nextFloat() * ALL_CHARS.length()); + random.append(ALL_CHARS.charAt(index)); + } + String id = random.toString(); + if (USED_IDS.get(id) != null) { + while (USED_IDS.get(id)) { + id = generateId(); + } + } + return id; + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/User.java b/commander/src/main/java/com/iluwatar/commander/User.java new file mode 100644 index 000000000000..85c5b92735c1 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/User.java @@ -0,0 +1,39 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +/** + * User class contains details of user who places order. + */ + +public class User { + String name; + String address; + + User(String name, String address) { + this.name = name; + this.address = address; + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java new file mode 100644 index 000000000000..729ba7ecbc73 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeDatabase.java @@ -0,0 +1,51 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.employeehandle; + +import java.util.Hashtable; +import com.iluwatar.commander.Database; +import com.iluwatar.commander.Order; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * The Employee Database is where orders which have encountered some issue(s) are added. + */ + +public class EmployeeDatabase extends Database { + private Hashtable data; + + public EmployeeDatabase() { + this.data = new Hashtable(); + } + + @Override + public Order add(Order o) throws DatabaseUnavailableException { + return data.put(o.id,o); + } + + @Override + public Order get(String oId) throws DatabaseUnavailableException { + return data.get(oId); + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeHandle.java b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeHandle.java new file mode 100644 index 000000000000..38e0747304cd --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/employeehandle/EmployeeHandle.java @@ -0,0 +1,54 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.employeehandle; + +import com.iluwatar.commander.Order; +import com.iluwatar.commander.Service; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * The EmployeeHandle class is the middle-man between {@link Commander} and + * {@link EmployeeDatabase}. + */ + +public class EmployeeHandle extends Service { + + public EmployeeHandle(EmployeeDatabase db, Exception...exc) { + super(db, exc); + } + + public String receiveRequest(Object...parameters) throws DatabaseUnavailableException { + return updateDb((Order)parameters[0]); + } + + protected String updateDb(Object...parameters) throws DatabaseUnavailableException { + Order o = (Order) parameters[0]; + if (database.get(o.id) == null) { + database.add(o); + return o.id; //true rcvd - change addedToEmployeeHandle to true else dont do anything + } + return null; + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/exceptions/DatabaseUnavailableException.java b/commander/src/main/java/com/iluwatar/commander/exceptions/DatabaseUnavailableException.java new file mode 100644 index 000000000000..95cf3982513f --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/exceptions/DatabaseUnavailableException.java @@ -0,0 +1,33 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.exceptions; + +/** + * DatabaseUnavailableException is thrown when database is unavailable and nothing + * can be added or retrieved. + */ + +public class DatabaseUnavailableException extends Exception { + private static final long serialVersionUID = 2459603L; +} diff --git a/commander/src/main/java/com/iluwatar/commander/exceptions/IsEmptyException.java b/commander/src/main/java/com/iluwatar/commander/exceptions/IsEmptyException.java new file mode 100644 index 000000000000..c51a82d52d7d --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/exceptions/IsEmptyException.java @@ -0,0 +1,32 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.exceptions; + +/** + * IsEmptyException is thrown when it is attempted to dequeue from an empty queue. + */ + +public class IsEmptyException extends Exception { + private static final long serialVersionUID = 123546L; +} diff --git a/commander/src/main/java/com/iluwatar/commander/exceptions/ItemUnavailableException.java b/commander/src/main/java/com/iluwatar/commander/exceptions/ItemUnavailableException.java new file mode 100644 index 000000000000..6c7a52ba70d1 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/exceptions/ItemUnavailableException.java @@ -0,0 +1,32 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.exceptions; + +/** + * ItemUnavailableException is thrown when item is not available for shipping. + */ + +public class ItemUnavailableException extends Exception { + private static final long serialVersionUID = 575940L; +} diff --git a/commander/src/main/java/com/iluwatar/commander/exceptions/PaymentDetailsErrorException.java b/commander/src/main/java/com/iluwatar/commander/exceptions/PaymentDetailsErrorException.java new file mode 100644 index 000000000000..ee36b105f591 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/exceptions/PaymentDetailsErrorException.java @@ -0,0 +1,33 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.exceptions; + +/** + * PaymentDetailsErrorException is thrown when the details entered are incorrect or + * payment cannot be made with the details given. + */ + +public class PaymentDetailsErrorException extends Exception { + private static final long serialVersionUID = 867203L; +} diff --git a/commander/src/main/java/com/iluwatar/commander/exceptions/ShippingNotPossibleException.java b/commander/src/main/java/com/iluwatar/commander/exceptions/ShippingNotPossibleException.java new file mode 100644 index 000000000000..0ef7673a129d --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/exceptions/ShippingNotPossibleException.java @@ -0,0 +1,33 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.exceptions; + +/** + * ShippingNotPossibleException is thrown when the address entered cannot be shipped to + * by service currently for some reason. + */ + +public class ShippingNotPossibleException extends Exception { + private static final long serialVersionUID = 342055L; +} diff --git a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java new file mode 100644 index 000000000000..2036a233cbd1 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingDatabase.java @@ -0,0 +1,52 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.messagingservice; + +import java.util.Hashtable; +import com.iluwatar.commander.Database; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.messagingservice.MessagingService.MessageRequest; + +/** + * The MessagingDatabase is where the MessageRequest is added. + */ + +public class MessagingDatabase extends Database { + private Hashtable data; + + public MessagingDatabase() { + this.data = new Hashtable(); + } + + @Override + public MessageRequest add(MessageRequest r) throws DatabaseUnavailableException { + return data.put(r.reqId, r); + } + + @Override + public MessageRequest get(String rId) throws DatabaseUnavailableException { + return data.get(rId); + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java new file mode 100644 index 000000000000..99cba87223d6 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/messagingservice/MessagingService.java @@ -0,0 +1,95 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.messagingservice; + +import com.iluwatar.commander.Service; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * The MessagingService is used to send messages to user regarding their order and + * payment status. In case an error is encountered in payment and this service is + * found to be unavailable, the order is added to the {@link EmployeeDatabase}. + */ + +public class MessagingService extends Service { + + enum MessageToSend { + PaymentFail, PaymentTrying, PaymentSuccessful + }; + + class MessageRequest { + String reqId; + MessageToSend msg; + + MessageRequest(String reqId, MessageToSend msg) { + this.reqId = reqId; + this.msg = msg; + } + } + + public MessagingService(MessagingDatabase db, Exception...exc) { + super(db, exc); + } + + /** + * Public method which will receive request from {@link Commander}. + */ + + public String receiveRequest(Object...parameters) throws DatabaseUnavailableException { + int messageToSend = (int) parameters[0]; + String rId = generateId(); + MessageToSend msg = null; + if (messageToSend == 0) { + msg = MessageToSend.PaymentFail; + } else if (messageToSend == 1) { + msg = MessageToSend.PaymentTrying; + } else { //messageToSend == 2 + msg = MessageToSend.PaymentSuccessful; + } + MessageRequest req = new MessageRequest(rId, msg); + return updateDb(req); + } + + protected String updateDb(Object...parameters) throws DatabaseUnavailableException { + MessageRequest req = (MessageRequest) parameters[0]; + if (this.database.get(req.reqId) == null) { //idempotence, in case db fails here + database.add(req); //if successful: + System.out.println(sendMessage(req.msg)); + return req.reqId; + } + return null; + } + + String sendMessage(MessageToSend m) { + if (m.equals(MessageToSend.PaymentSuccessful)) { + return "Msg: Your order has been placed and paid for successfully! Thank you for shopping with us!"; + } else if (m.equals(MessageToSend.PaymentTrying)) { + 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."; + } else { + return "Msg: There was an error in your payment process. Your order is placed and has been converted to COD." + + " Please reach us on CUSTOMER-CARE-NUBER in case of any queries. Thank you for shopping with us!"; + } + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java new file mode 100644 index 000000000000..39e3664d6b73 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentDatabase.java @@ -0,0 +1,55 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.paymentservice; + +import java.util.Hashtable; + +import com.iluwatar.commander.Database; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.paymentservice.PaymentService.PaymentRequest; + +/** + * PaymentDatabase is where the PaymentRequest is added, along with details. + */ + +public class PaymentDatabase extends Database { + + private Hashtable data; + + public PaymentDatabase() { + this.data = new Hashtable(); + //0-fail, 1-error, 2-success + } + + @Override + public PaymentRequest add(PaymentRequest r) throws DatabaseUnavailableException { + return data.put(r.transactionId, r); + } + + @Override + public PaymentRequest get(String tId) throws DatabaseUnavailableException { + return data.get(tId); + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentService.java b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentService.java new file mode 100644 index 000000000000..a3df0ce096e9 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/paymentservice/PaymentService.java @@ -0,0 +1,72 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.paymentservice; + +import com.iluwatar.commander.Service; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * The PaymentService class receives request from the {@link Commander} and adds + * to the {@link PaymentDatabase}. + */ + +public class PaymentService extends Service { + + class PaymentRequest { + String transactionId; + float payment; + boolean paid; + + PaymentRequest(String transactionId, float payment) { + this.transactionId = transactionId; + this.payment = payment; + this.paid = false; + } + } + + public PaymentService(PaymentDatabase db, Exception...exc) { + super(db, exc); + } + + /** + * Public method which will receive request from {@link Commander}. + */ + + public String receiveRequest(Object...parameters) throws DatabaseUnavailableException { + //it could also be sending a userid, payment details here or something, not added here + String tId = generateId(); + PaymentRequest req = new PaymentRequest(tId, (float)parameters[0]); + return updateDb(req); + } + + protected String updateDb(Object...parameters) throws DatabaseUnavailableException { + PaymentRequest req = (PaymentRequest) parameters[0]; + if (database.get(req.transactionId) == null || !req.paid) { + database.add(req); + req.paid = true; + return req.transactionId; + } + return null; + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/queue/Queue.java b/commander/src/main/java/com/iluwatar/commander/queue/Queue.java new file mode 100644 index 000000000000..f1b0ef533117 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/queue/Queue.java @@ -0,0 +1,97 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.queue; + +import com.iluwatar.commander.exceptions.IsEmptyException; + +/** + * Queue data structure implementation. + * @param is the type of object the queue will hold. + */ + +public class Queue { + + Node front; + Node rear; + public int size = 0; + + class Node { + T value; + Node next; + + Node(T obj, Node b) { + value = obj; + next = b; + } + } + + /** + * Queue constructor + */ + + Queue() { + front = null; + rear = null; + size = 0; + } + + boolean isEmpty() { + if (size == 0) { + return true; + } else { + return false; + } + } + + void enqueue(T obj) { + if (front == null) { + front = new Node(obj, null); + rear = front; + } else { + Node temp = new Node(obj, null); + rear.next = temp; + rear = temp; + } + size++; + } + + T dequeue() throws IsEmptyException { + if (isEmpty()) { + throw new IsEmptyException(); + } else { + Node temp = front; + front = front.next; + size = size - 1; + return ((T) temp.value); + } + } + + T peek() throws IsEmptyException { + if (isEmpty()) { + throw new IsEmptyException(); + } else { + return ((T)front.value); + } + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java new file mode 100644 index 000000000000..8ecd8c0a88e9 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/queue/QueueDatabase.java @@ -0,0 +1,82 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.queue; + +import java.util.ArrayList; +import java.util.Arrays; +import com.iluwatar.commander.Database; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.IsEmptyException; + +/** + * QueueDatabase id where the instructions to be implemented are queued. + */ + +public class QueueDatabase extends Database { + + private Queue data; + public ArrayList exceptionsList; + + public QueueDatabase(Exception...exc) { + this.data = new Queue(); + this.exceptionsList = new ArrayList(Arrays.asList(exc)); + } + + @Override + public QueueTask add(QueueTask t) throws DatabaseUnavailableException { + data.enqueue(t); + return t; + //even if same thing queued twice, it is taken care of in other dbs + } + + /** + * peek method returns object at front without removing it from queue + * @return object at front of queue + * @throws IsEmptyException if queue is empty + * @throws DatabaseUnavailableException if queue db is unavailable + */ + + public QueueTask peek() throws IsEmptyException, DatabaseUnavailableException { + QueueTask qt = this.data.peek(); + return qt; + } + + /** + * dequeue method removes the object at front and returns it + * @return object at front of queue + * @throws IsEmptyException if queue is empty + * @throws DatabaseUnavailableException if queue db is unavailable + */ + + public QueueTask dequeue() throws IsEmptyException, DatabaseUnavailableException { + QueueTask qt = this.data.dequeue(); + return qt; + } + + @Override + public QueueTask get(String tId) throws DatabaseUnavailableException { + return null; + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java b/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java new file mode 100644 index 000000000000..7e4219997978 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/queue/QueueTask.java @@ -0,0 +1,82 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.queue; + +import com.iluwatar.commander.Order; + +/** + * QueueTask object is the object enqueued in queue. + */ + +public class QueueTask { + +/** + * TaskType is the type of task to be done. + */ + + public enum TaskType { + Messaging, Payment, EmployeeDb + }; + + public Order order; + public TaskType taskType; + public int messageType; //0-fail, 1-error, 2-success + /*we could have varargs Object instead to pass in any parameter instead of just message type + but keeping it simple here*/ + public long firstAttemptTime; //when first time attempt made to do task + +/** + * QueueTask constructor + * @param o is the order for which the queuetask is being created + * @param t is the type of task to be done + * @param messageType if it is a message, which type of message - this could have instead been object varargs, + * and contained all additional details related to tasktype. + */ + + public QueueTask(Order o, TaskType t, int messageType) { + this.order = o; + this.taskType = t; + this.messageType = messageType; + this.firstAttemptTime = -1; + } + + /** + * getType method + * @return String representing type of task + */ + + public String getType() { + if (!this.taskType.equals(TaskType.Messaging)) { + return this.taskType.toString(); + } else { + if (this.messageType == 0) { + return "Payment Failure Message"; + } else if (this.messageType == 1) { + return "Payment Error Message"; + } else { + return "Payment Success Message"; + } + } + } +} diff --git a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java new file mode 100644 index 000000000000..145a82437c32 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingDatabase.java @@ -0,0 +1,52 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.shippingservice; + +import java.util.Hashtable; +import com.iluwatar.commander.Database; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.shippingservice.ShippingService.ShippingRequest; + +/** + * ShippingDatabase is where the ShippingRequest objects are added. + */ + +public class ShippingDatabase extends Database { + + private Hashtable data; + + public ShippingDatabase() { + this.data = new Hashtable(); + } + + @Override + public ShippingRequest add(ShippingRequest r) throws DatabaseUnavailableException { + return data.put(r.transactionId, r); + } + + public ShippingRequest get(String transactionId) throws DatabaseUnavailableException { + return data.get(transactionId); + } + +} diff --git a/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingService.java b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingService.java new file mode 100644 index 000000000000..02d3430a8013 --- /dev/null +++ b/commander/src/main/java/com/iluwatar/commander/shippingservice/ShippingService.java @@ -0,0 +1,70 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander.shippingservice; + +import com.iluwatar.commander.Service; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; + +/** + * ShippingService class receives request from {@link Commander} class and adds it + * to the {@link ShippingDatabase}. + */ + +public class ShippingService extends Service { + + class ShippingRequest { + String transactionId; + String item; + String address; + + ShippingRequest(String transactionId, String item, String address) { + this.transactionId = transactionId; + this.item = item; + this.address = address; + } + } + + public ShippingService(ShippingDatabase db, Exception...exc) { + super(db, exc); + } + + /** + * Public method which will receive request from {@link Commander}. + */ + + public String receiveRequest(Object...parameters) throws DatabaseUnavailableException { + String tId = generateId(); + ShippingRequest req = new ShippingRequest(tId, (String) parameters[0] /*item*/, (String) parameters[1]/*address*/); + return updateDb(req); + } + + protected String updateDb(Object...parameters) throws DatabaseUnavailableException { + ShippingRequest req = (ShippingRequest) parameters[0]; + if (this.database.get(req.transactionId) == null) { + database.add(req); + return req.transactionId; + } + return null; + } +} diff --git a/commander/src/test/java/com/iluwatar/commander/RetryTest.java b/commander/src/test/java/com/iluwatar/commander/RetryTest.java new file mode 100644 index 000000000000..7a732f199071 --- /dev/null +++ b/commander/src/test/java/com/iluwatar/commander/RetryTest.java @@ -0,0 +1,76 @@ +/** + * The MIT License + * Copyright (c) 2014-2016 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.commander; + +import static org.junit.jupiter.api.Assertions.*; +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +import com.iluwatar.commander.Order; +import com.iluwatar.commander.Retry; +import com.iluwatar.commander.User; +import com.iluwatar.commander.Retry.HandleErrorIssue; +import com.iluwatar.commander.Retry.Operation; +import com.iluwatar.commander.exceptions.DatabaseUnavailableException; +import com.iluwatar.commander.exceptions.ItemUnavailableException; + +class RetryTest { + + @Test + void performTest() { + Retry.Operation op = (l) -> { + if (!l.isEmpty()) { + throw l.remove(0); + } + return; + }; + Retry.HandleErrorIssue handleError = (o,e) -> { + return; + }; + Retry r1 = new Retry(op, handleError, 3, 30000, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + Retry r2 = new Retry(op, handleError, 3, 30000, + e -> DatabaseUnavailableException.class.isAssignableFrom(e.getClass())); + User user = new User("Jim", "ABCD"); + Order order = new Order(user, "book", 10f); + ArrayList arr1 = new ArrayList(Arrays.asList(new Exception[] + {new ItemUnavailableException(), new DatabaseUnavailableException()})); + try { + r1.perform(arr1, order); + } catch (Exception e1) { + e1.printStackTrace(); + } + ArrayList arr2 = new ArrayList(Arrays.asList(new Exception[] + {new DatabaseUnavailableException(), new ItemUnavailableException()})); + try { + r2.perform(arr2, order); + } catch (Exception e1) { + e1.printStackTrace(); + } + //r1 stops at ItemUnavailableException, r2 retries because it encounters DatabaseUnavailableException + assertTrue(arr1.size() == 1 && arr2.size() == 0); + } + +} diff --git a/pom.xml b/pom.xml index 014e67bda525..e83a7c24a210 100644 --- a/pom.xml +++ b/pom.xml @@ -166,6 +166,7 @@ collection-pipeline master-worker-pattern spatial-partition + commander typeobjectpattern From 2757b210ea77be9bcd7645cee884e1483508a13a Mon Sep 17 00:00:00 2001 From: hoangnam2261 <31692990+hoangnam2261@users.noreply.github.com> Date: Tue, 30 Jul 2019 01:12:14 +0700 Subject: [PATCH 07/28] Best practice when compare enum (#869) --- chain/src/main/java/com/iluwatar/chain/OrcCommander.java | 2 +- chain/src/main/java/com/iluwatar/chain/OrcOfficer.java | 2 +- chain/src/main/java/com/iluwatar/chain/OrcSoldier.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/src/main/java/com/iluwatar/chain/OrcCommander.java b/chain/src/main/java/com/iluwatar/chain/OrcCommander.java index 048ba495457f..073ea257e740 100644 --- a/chain/src/main/java/com/iluwatar/chain/OrcCommander.java +++ b/chain/src/main/java/com/iluwatar/chain/OrcCommander.java @@ -35,7 +35,7 @@ public OrcCommander(RequestHandler handler) { @Override public void handleRequest(Request req) { - if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) { + if (RequestType.DEFEND_CASTLE == req.getRequestType()) { printHandling(req); req.markHandled(); } else { diff --git a/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java b/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java index 8e90b7ca0bdb..2c2902266d4f 100644 --- a/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java +++ b/chain/src/main/java/com/iluwatar/chain/OrcOfficer.java @@ -35,7 +35,7 @@ public OrcOfficer(RequestHandler handler) { @Override public void handleRequest(Request req) { - if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) { + if (RequestType.TORTURE_PRISONER == req.getRequestType()) { printHandling(req); req.markHandled(); } else { diff --git a/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java b/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java index 99e0d5022348..adc25fb2bc44 100644 --- a/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java +++ b/chain/src/main/java/com/iluwatar/chain/OrcSoldier.java @@ -35,7 +35,7 @@ public OrcSoldier(RequestHandler handler) { @Override public void handleRequest(Request req) { - if (req.getRequestType().equals(RequestType.COLLECT_TAX)) { + if (RequestType.COLLECT_TAX == req.getRequestType()) { printHandling(req); req.markHandled(); } else { From aaabc8f517461593d206a009858cefd163e43daa Mon Sep 17 00:00:00 2001 From: HelloCoCooo <46306510+HelloCoCooo@users.noreply.github.com> Date: Tue, 30 Jul 2019 02:16:21 +0800 Subject: [PATCH 08/28] Fix the dependency conflict issue (#872) --- api-gateway/api-gateway-service/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml index f947049a757c..13bbddc97d09 100644 --- a/api-gateway/api-gateway-service/pom.xml +++ b/api-gateway/api-gateway-service/pom.xml @@ -48,6 +48,10 @@ org.springframework spring-webmvc + + org.apache.httpcomponents + httpclient + org.springframework.boot spring-boot-starter-web @@ -67,10 +71,6 @@ mockito-core test - - org.apache.httpcomponents - httpclient - @@ -89,4 +89,4 @@ -
\ No newline at end of file + From b497d41f61b43e188f43fa0f3f70b3a2e164bb76 Mon Sep 17 00:00:00 2001 From: DRad Date: Mon, 29 Jul 2019 20:21:07 +0200 Subject: [PATCH 09/28] Modify Observer pattern UML (#877) --- observer/README.md | 2 +- observer/etc/observer.png | Bin 20227 -> 18867 bytes observer/etc/observer.ucls | 40 ++++++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/observer/README.md b/observer/README.md index 38a28032f957..afeb0b37d68d 100644 --- a/observer/README.md +++ b/observer/README.md @@ -19,7 +19,7 @@ Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. -![alt text](./etc/observer_1.png "Observer") +![alt text](./etc/observer.png "Observer") ## Applicability Use the Observer pattern in any of the following situations diff --git a/observer/etc/observer.png b/observer/etc/observer.png index 40f112d03217b68755ad451d328716657522313c..f2ab0edfeb2159992c40c7fc3b684d4a0f7e02cd 100644 GIT binary patch literal 18867 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 literal 20227 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 Mr>mdKI;Vst0Mv@py8r+H diff --git a/observer/etc/observer.ucls b/observer/etc/observer.ucls index 87a3dd216d4e..ac1d267f89b8 100644 --- a/observer/etc/observer.ucls +++ b/observer/etc/observer.ucls @@ -1,9 +1,9 @@ - + - + @@ -12,7 +12,7 @@ - + @@ -21,7 +21,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -39,7 +39,7 @@ - + @@ -48,28 +48,36 @@ - - + + + + + + + + + + - + - - + + + + + + - - - - From 3454941dcde93a9497160a43e7520cb2036af69d Mon Sep 17 00:00:00 2001 From: pierDipi <33736985+pierDipi@users.noreply.github.com> Date: Mon, 29 Jul 2019 20:22:56 +0200 Subject: [PATCH 10/28] Typo coresponding -> corresponding (#879) --- converter/src/main/java/com/iluwatar/converter/Converter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/converter/src/main/java/com/iluwatar/converter/Converter.java b/converter/src/main/java/com/iluwatar/converter/Converter.java index 4a2bb7381ede..a4a73f0c7e1a 100644 --- a/converter/src/main/java/com/iluwatar/converter/Converter.java +++ b/converter/src/main/java/com/iluwatar/converter/Converter.java @@ -30,7 +30,7 @@ /** * Generic converter, thanks to Java8 features not only provides a way of generic bidirectional - * conversion between coresponding types, but also a common way of converting a collection of objects + * conversion between corresponding types, but also a common way of converting a collection of objects * of the same type, reducing boilerplate code to the absolute minimum. * @param DTO representation's type * @param Domain representation's type From 36e80c4e692c37060fc9e4cb824d28c1eef1fa68 Mon Sep 17 00:00:00 2001 From: S Sethi Date: Mon, 29 Jul 2019 19:27:08 +0100 Subject: [PATCH 11/28] fixed failing tests (#860) (#880) --- .../java/com/iluwatar/twin/BallThreadTest.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/twin/src/test/java/com/iluwatar/twin/BallThreadTest.java b/twin/src/test/java/com/iluwatar/twin/BallThreadTest.java index 88fb0345e895..6e46cd4f1af5 100644 --- a/twin/src/test/java/com/iluwatar/twin/BallThreadTest.java +++ b/twin/src/test/java/com/iluwatar/twin/BallThreadTest.java @@ -30,11 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertTimeout; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.*; /** * Date: 12/30/15 - 18:55 PM @@ -55,9 +51,9 @@ public void testSuspend() throws Exception { ballThread.setTwin(ballItem); ballThread.start(); - - verify(ballItem, timeout(2000).atLeastOnce()).draw(); - verify(ballItem, timeout(2000).atLeastOnce()).move(); + sleep(200); + verify(ballItem, atLeastOnce()).draw(); + verify(ballItem, atLeastOnce()).move(); ballThread.suspendMe(); sleep(1000); @@ -88,8 +84,9 @@ public void testResume() { verifyZeroInteractions(ballItem); ballThread.resumeMe(); - verify(ballItem, timeout(2000).atLeastOnce()).draw(); - verify(ballItem, timeout(2000).atLeastOnce()).move(); + sleep(200); + verify(ballItem, atLeastOnce()).draw(); + verify(ballItem, atLeastOnce()).move(); ballThread.stopMe(); ballThread.join(); From 517c20960d1ac42c1c6a031df360baf27ef8d683 Mon Sep 17 00:00:00 2001 From: Thiago Medeiros Date: Mon, 29 Jul 2019 15:31:42 -0300 Subject: [PATCH 12/28] Added one more Credit/Article about the benefits of Repository pattern (#882) --- repository/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/repository/README.md b/repository/README.md index 67b3ea44e828..b1f4fb97f56c 100644 --- a/repository/README.md +++ b/repository/README.md @@ -35,3 +35,4 @@ Use the Repository pattern when * [Don’t use DAO, use Repository](http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/) * [Advanced Spring Data JPA - Specifications and Querydsl](https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/) +* [Repository Pattern Benefits and Spring Implementation](https://stackoverflow.com/questions/40068965/repository-pattern-benefits-and-spring-implementation) \ No newline at end of file From 6daaeec5c664108224d0dd6484032ed897f36fca Mon Sep 17 00:00:00 2001 From: hoangnam2261 <31692990+hoangnam2261@users.noreply.github.com> Date: Wed, 31 Jul 2019 02:46:38 +0700 Subject: [PATCH 13/28] Remove the transitive dependency(junit-jupiter-api) (#916) --- abstract-document/pom.xml | 7 +- abstract-factory/pom.xml | 5 - acyclic-visitor/pom.xml | 5 - adapter/pom.xml | 5 - .../aggregator-service/pom.xml | 7 +- .../information-microservice/pom.xml | 5 - .../inventory-microservice/pom.xml | 7 +- ambassador/pom.xml | 7 +- api-gateway/api-gateway-service/pom.xml | 5 - api-gateway/image-microservice/pom.xml | 7 +- api-gateway/price-microservice/pom.xml | 7 +- async-method-invocation/pom.xml | 5 - balking/pom.xml | 7 +- bridge/pom.xml | 5 - builder/pom.xml | 5 - business-delegate/pom.xml | 5 - caching/pom.xml | 5 - callback/pom.xml | 5 - chain/pom.xml | 5 - collection-pipeline/pom.xml | 7 +- command/pom.xml | 5 - commander/pom.xml | 7 +- composite/pom.xml | 5 - converter/pom.xml | 5 - cqrs/pom.xml | 5 - dao/pom.xml | 5 - data-bus/pom.xml | 5 - data-mapper/pom.xml | 95 +++++++++---------- data-transfer-object/pom.xml | 5 - decorator/pom.xml | 5 - delegation/pom.xml | 7 +- dependency-injection/pom.xml | 5 - dirty-flag/pom.xml | 5 - double-checked-locking/pom.xml | 5 - double-dispatch/pom.xml | 5 - eip-aggregator/pom.xml | 7 +- eip-message-channel/pom.xml | 5 - eip-publish-subscribe/pom.xml | 5 - eip-splitter/pom.xml | 7 +- eip-wire-tap/pom.xml | 7 +- event-aggregator/pom.xml | 5 - event-asynchronous/pom.xml | 5 - event-driven-architecture/pom.xml | 7 +- event-queue/pom.xml | 7 +- event-sourcing/pom.xml | 7 +- execute-around/pom.xml | 5 - extension-objects/pom.xml | 5 - facade/pom.xml | 5 - factory-kit/pom.xml | 7 +- factory-method/pom.xml | 5 - feature-toggle/pom.xml | 7 +- fluentinterface/pom.xml | 7 +- flux/pom.xml | 5 - flyweight/pom.xml | 5 - front-controller/pom.xml | 5 - guarded-suspension/pom.xml | 7 +- half-sync-half-async/pom.xml | 5 - hexagonal/pom.xml | 5 - intercepting-filter/pom.xml | 5 - interpreter/pom.xml | 5 - iterator/pom.xml | 5 - layers/pom.xml | 5 - lazy-loading/pom.xml | 5 - marker/pom.xml | 5 - master-worker-pattern/pom.xml | 5 - mediator/pom.xml | 5 - memento/pom.xml | 5 - model-view-controller/pom.xml | 5 - model-view-presenter/pom.xml | 5 - module/pom.xml | 5 - monad/pom.xml | 5 - monostate/pom.xml | 5 - multiton/pom.xml | 5 - mute-idiom/pom.xml | 5 - mutex/pom.xml | 5 - null-object/pom.xml | 5 - object-mother/pom.xml | 7 +- object-pool/pom.xml | 5 - observer/pom.xml | 5 - page-object/test-automation/pom.xml | 7 +- poison-pill/pom.xml | 5 - pom.xml | 8 +- private-class-data/pom.xml | 5 - producer-consumer/pom.xml | 5 - promise/pom.xml | 5 - property/pom.xml | 5 - prototype/pom.xml | 5 - proxy/pom.xml | 5 - queue-load-leveling/pom.xml | 5 - reactor/pom.xml | 5 - reader-writer-lock/pom.xml | 5 - repository/pom.xml | 5 - .../pom.xml | 5 - retry/pom.xml | 7 +- semaphore/pom.xml | 5 - servant/pom.xml | 5 - serverless/pom.xml | 7 +- service-layer/pom.xml | 5 - service-locator/pom.xml | 5 - singleton/pom.xml | 5 - spatial-partition/pom.xml | 5 - specification/pom.xml | 5 - state/pom.xml | 5 - step-builder/pom.xml | 7 +- strategy/pom.xml | 5 - template-method/pom.xml | 5 - thread-pool/pom.xml | 5 - throttling/pom.xml | 7 +- tls/pom.xml | 91 +++++++++--------- tolerant-reader/pom.xml | 5 - trampoline/pom.xml | 5 - twin/pom.xml | 5 - typeobjectpattern/pom.xml | 7 +- value-object/pom.xml | 5 - visitor/pom.xml | 5 - 115 files changed, 116 insertions(+), 692 deletions(-) diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml index de6ef506982c..bdcdd170a43a 100644 --- a/abstract-document/pom.xml +++ b/abstract-document/pom.xml @@ -33,15 +33,10 @@ abstract-document - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index 57bbdb5bbb98..00c9a491cf15 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -33,11 +33,6 @@ abstract-factory - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/acyclic-visitor/pom.xml b/acyclic-visitor/pom.xml index 8ce2b1e27586..4a0f740fdd42 100644 --- a/acyclic-visitor/pom.xml +++ b/acyclic-visitor/pom.xml @@ -56,11 +56,6 @@ 1.0.0 test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/adapter/pom.xml b/adapter/pom.xml index b417432c2aab..0c47247dd8a7 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -33,11 +33,6 @@ adapter - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml index 626ddcd0ba4f..c4ad9cf1a4a9 100644 --- a/aggregator-microservices/aggregator-service/pom.xml +++ b/aggregator-microservices/aggregator-service/pom.xml @@ -53,11 +53,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -90,4 +85,4 @@ - \ No newline at end of file + diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml index bac47c19c73c..85992658990b 100644 --- a/aggregator-microservices/information-microservice/pom.xml +++ b/aggregator-microservices/information-microservice/pom.xml @@ -53,11 +53,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml index bf613916b3ae..e19ba55533fb 100644 --- a/aggregator-microservices/inventory-microservice/pom.xml +++ b/aggregator-microservices/inventory-microservice/pom.xml @@ -53,11 +53,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -81,4 +76,4 @@ - \ No newline at end of file + diff --git a/ambassador/pom.xml b/ambassador/pom.xml index 6bfbf50084b1..efc8437051fe 100644 --- a/ambassador/pom.xml +++ b/ambassador/pom.xml @@ -34,15 +34,10 @@ 4.0.0 ambassador - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml index 13bbddc97d09..b17d71bfb905 100644 --- a/api-gateway/api-gateway-service/pom.xml +++ b/api-gateway/api-gateway-service/pom.xml @@ -56,11 +56,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/api-gateway/image-microservice/pom.xml b/api-gateway/image-microservice/pom.xml index 928b23ed699e..bf70cda03c74 100644 --- a/api-gateway/image-microservice/pom.xml +++ b/api-gateway/image-microservice/pom.xml @@ -53,11 +53,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -81,4 +76,4 @@ - \ No newline at end of file + diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml index 58730846d6f2..33931cac5b2d 100644 --- a/api-gateway/price-microservice/pom.xml +++ b/api-gateway/price-microservice/pom.xml @@ -53,11 +53,6 @@ org.springframework.boot spring-boot-starter-web - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -81,4 +76,4 @@ - \ No newline at end of file + diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 28e9705f26c7..0c42bc970333 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -33,11 +33,6 @@ async-method-invocation - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/balking/pom.xml b/balking/pom.xml index 500a11c82f6b..f20969b62765 100644 --- a/balking/pom.xml +++ b/balking/pom.xml @@ -35,11 +35,6 @@ balking - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -48,4 +43,4 @@ - \ No newline at end of file + diff --git a/bridge/pom.xml b/bridge/pom.xml index a86c5bf22c4d..cf45178a1925 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -33,11 +33,6 @@ bridge - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/builder/pom.xml b/builder/pom.xml index 9130209fffd2..dcf61fad5691 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -33,11 +33,6 @@ builder - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index 70ad2a1137b3..ab2f1ae3cb2e 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -34,11 +34,6 @@ business-delegate - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/caching/pom.xml b/caching/pom.xml index f86f8b2bab2f..c678aba4f4e4 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -33,11 +33,6 @@ caching - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/callback/pom.xml b/callback/pom.xml index 4506d0316c6a..46e9e2c9a5fe 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -33,11 +33,6 @@ callback - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/chain/pom.xml b/chain/pom.xml index 7ff678a154ca..86b469ed828f 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -33,11 +33,6 @@ chain - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml index 8c4aad2dd392..6003c9b4d7b3 100644 --- a/collection-pipeline/pom.xml +++ b/collection-pipeline/pom.xml @@ -31,15 +31,10 @@ collection-pipeline - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/command/pom.xml b/command/pom.xml index 6807764561ef..6d22f80a3ef1 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -33,11 +33,6 @@ command - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/commander/pom.xml b/commander/pom.xml index 895906e65ded..bbf69b597113 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -7,11 +7,6 @@ commander - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -23,4 +18,4 @@ 1.2.17 - \ No newline at end of file + diff --git a/composite/pom.xml b/composite/pom.xml index 60142cf9061c..9d6f53e2cf08 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -33,11 +33,6 @@ composite - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/converter/pom.xml b/converter/pom.xml index 4caf7b203dc9..18b70a1d1e01 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -33,11 +33,6 @@ 4.0.0 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/cqrs/pom.xml b/cqrs/pom.xml index 6480f25e9b0f..428a9943a2f2 100644 --- a/cqrs/pom.xml +++ b/cqrs/pom.xml @@ -25,11 +25,6 @@ cqrs - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/dao/pom.xml b/dao/pom.xml index 20eb79c535b3..addefc20873b 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -35,11 +35,6 @@ dao - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/data-bus/pom.xml b/data-bus/pom.xml index 9106191af529..918da99040d1 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -37,11 +37,6 @@ data-bus - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml index bbcf42ee6b5d..e64f44747e55 100644 --- a/data-mapper/pom.xml +++ b/data-mapper/pom.xml @@ -1,50 +1,45 @@ - - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.21.0-SNAPSHOT - - data-mapper - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - log4j - log4j - - - + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.21.0-SNAPSHOT + + data-mapper + + + org.junit.jupiter + junit-jupiter-engine + test + + + log4j + log4j + + + diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index 3dcb2dc3ce4d..79a54564430e 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -32,11 +32,6 @@ data-transfer-object - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/decorator/pom.xml b/decorator/pom.xml index a9b9c361d11a..e92b9dc492b2 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -33,11 +33,6 @@ decorator - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/delegation/pom.xml b/delegation/pom.xml index 62bda23185ff..02b0fda4adeb 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -37,15 +37,10 @@ delegation - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 631fc6b7c03f..21873c86813c 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -33,11 +33,6 @@ dependency-injection - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index e91d6c9f4c25..de3ef48f0596 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -40,11 +40,6 @@ UTF-8 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index 999f78d878af..49ffe88a77fb 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -31,11 +31,6 @@ double-checked-locking - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 875c1b430247..22fe7a684bc3 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -33,11 +33,6 @@ double-dispatch - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml index 0cc3aa590d62..54de34334464 100644 --- a/eip-aggregator/pom.xml +++ b/eip-aggregator/pom.xml @@ -53,11 +53,6 @@ spring-test-junit5 test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -75,4 +70,4 @@ - \ No newline at end of file + diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml index 9b297f72995e..fd7ee5c0e5e8 100644 --- a/eip-message-channel/pom.xml +++ b/eip-message-channel/pom.xml @@ -42,11 +42,6 @@ org.apache.camel camel-stream - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml index c8bc4de28d7a..2a041930d048 100644 --- a/eip-publish-subscribe/pom.xml +++ b/eip-publish-subscribe/pom.xml @@ -40,11 +40,6 @@ org.apache.camel camel-stream - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml index 7cb722164492..3f5a79ca1dcc 100644 --- a/eip-splitter/pom.xml +++ b/eip-splitter/pom.xml @@ -53,11 +53,6 @@ spring-test-junit5 test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -75,4 +70,4 @@ - \ No newline at end of file + diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml index c9f569a554d8..e3791102d367 100644 --- a/eip-wire-tap/pom.xml +++ b/eip-wire-tap/pom.xml @@ -53,11 +53,6 @@ spring-test-junit5 test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -75,4 +70,4 @@ - \ No newline at end of file + diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index a6d473841d2e..dca72de732eb 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -32,11 +32,6 @@ event-aggregator - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/event-asynchronous/pom.xml b/event-asynchronous/pom.xml index 64e69adb629a..908662d083d9 100644 --- a/event-asynchronous/pom.xml +++ b/event-asynchronous/pom.xml @@ -33,11 +33,6 @@ event-asynchronous - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index 03ff66fed956..a336c9f13962 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -37,11 +37,6 @@ event-driven-architecture - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -54,4 +49,4 @@ test - \ No newline at end of file + diff --git a/event-queue/pom.xml b/event-queue/pom.xml index 65bb489c2b9b..bd80ba5a4bec 100644 --- a/event-queue/pom.xml +++ b/event-queue/pom.xml @@ -34,15 +34,10 @@ event-queue - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index bae5e997073c..4b4d8c701cfa 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -34,11 +34,6 @@ event-sourcing - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -52,4 +47,4 @@ - \ No newline at end of file + diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 8000c4e2f757..6fd853ff571f 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -33,11 +33,6 @@ execute-around - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/extension-objects/pom.xml b/extension-objects/pom.xml index 368ee8c36abc..2dee66d3aa46 100644 --- a/extension-objects/pom.xml +++ b/extension-objects/pom.xml @@ -35,11 +35,6 @@ extension-objects - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/facade/pom.xml b/facade/pom.xml index a658e4376af2..1b9bcb86ad4a 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -33,11 +33,6 @@ facade - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/factory-kit/pom.xml b/factory-kit/pom.xml index b6cb46b0ecc8..ac23757ec86d 100644 --- a/factory-kit/pom.xml +++ b/factory-kit/pom.xml @@ -34,15 +34,10 @@ factory-kit - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/factory-method/pom.xml b/factory-method/pom.xml index 9ea706365db2..226c80958e1d 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -33,11 +33,6 @@ factory-method - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 9f9f2678790c..bd0fb5d71ce5 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -38,15 +38,10 @@ - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index c648602e77cc..605537a73b8a 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -35,11 +35,6 @@ fluentinterface - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -51,4 +46,4 @@ test - \ No newline at end of file + diff --git a/flux/pom.xml b/flux/pom.xml index f28c8fbb0197..726df234a27a 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -33,11 +33,6 @@ flux - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 223fae694ea4..5bb8f2254950 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -33,11 +33,6 @@ flyweight - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/front-controller/pom.xml b/front-controller/pom.xml index af1e22fff073..27dc990d110a 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -34,11 +34,6 @@ front-controller - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/guarded-suspension/pom.xml b/guarded-suspension/pom.xml index 367d582d57d8..c944f8586951 100644 --- a/guarded-suspension/pom.xml +++ b/guarded-suspension/pom.xml @@ -35,15 +35,10 @@ jar guarded-suspension - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index e79a05037e03..a532c619347e 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -33,11 +33,6 @@ half-sync-half-async - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml index cb127c91d0f1..a2c9f1925d51 100644 --- a/hexagonal/pom.xml +++ b/hexagonal/pom.xml @@ -34,11 +34,6 @@ hexagonal - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index f38e6b4f2ae0..bf78e6792669 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -33,11 +33,6 @@ intercepting-filter - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/interpreter/pom.xml b/interpreter/pom.xml index 1e958fa3f70f..1274a4b69557 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -33,11 +33,6 @@ interpreter - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/iterator/pom.xml b/iterator/pom.xml index 9d1f4e280dbe..fa06c9d3b0f0 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -33,11 +33,6 @@ iterator - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/layers/pom.xml b/layers/pom.xml index b3cdf0ac76ba..cdd996ccb515 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -51,11 +51,6 @@ com.h2database h2 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index c7f3679ae32d..773dd7d8bed6 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -33,11 +33,6 @@ lazy-loading - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/marker/pom.xml b/marker/pom.xml index 168abaee8b12..faa6868c237d 100644 --- a/marker/pom.xml +++ b/marker/pom.xml @@ -30,11 +30,6 @@ marker - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index 6b413ea64c63..1c317bac9446 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -31,11 +31,6 @@ master-worker-pattern - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/mediator/pom.xml b/mediator/pom.xml index 83cc0f70d93f..d14e82bcc522 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -33,11 +33,6 @@ mediator - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/memento/pom.xml b/memento/pom.xml index 8846bcdcc813..fc3e1954f76d 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -33,11 +33,6 @@ memento - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index d2b223dc2615..523319a28e50 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -33,11 +33,6 @@ model-view-controller - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index a0f7d31b23b5..a4e91652820d 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -35,11 +35,6 @@ model-view-presenter http://maven.apache.org - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/module/pom.xml b/module/pom.xml index 56e0a8b35715..0320d97c0a8f 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -32,11 +32,6 @@ module - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/monad/pom.xml b/monad/pom.xml index 2e2e34870830..45741ee1b6e7 100644 --- a/monad/pom.xml +++ b/monad/pom.xml @@ -33,11 +33,6 @@ monad - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/monostate/pom.xml b/monostate/pom.xml index 920311a8bac7..d39071e261ea 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -33,11 +33,6 @@ monostate - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/multiton/pom.xml b/multiton/pom.xml index f1abf43a13f0..beaccf3e3db8 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -33,11 +33,6 @@ multiton - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/mute-idiom/pom.xml b/mute-idiom/pom.xml index b3f8d8aaf9b0..7cdbc5a42e0a 100644 --- a/mute-idiom/pom.xml +++ b/mute-idiom/pom.xml @@ -25,11 +25,6 @@ mute-idiom - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/mutex/pom.xml b/mutex/pom.xml index ed9e6b264dbc..85c5208d83b1 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -33,11 +33,6 @@ mutex - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/null-object/pom.xml b/null-object/pom.xml index 099fcfce32eb..5c35e6a0a9e0 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -33,11 +33,6 @@ null-object - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/object-mother/pom.xml b/object-mother/pom.xml index d22633313ef9..c0ed50739c74 100644 --- a/object-mother/pom.xml +++ b/object-mother/pom.xml @@ -34,11 +34,6 @@ object-mother - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -50,4 +45,4 @@ test - \ No newline at end of file + diff --git a/object-pool/pom.xml b/object-pool/pom.xml index 6ad7823c46f7..fcb95db29fea 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -33,11 +33,6 @@ object-pool - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/observer/pom.xml b/observer/pom.xml index 80720f6a2d0a..2248957c7179 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -33,11 +33,6 @@ observer - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/page-object/test-automation/pom.xml b/page-object/test-automation/pom.xml index 618eadb20e68..7f8bcb12d0e9 100644 --- a/page-object/test-automation/pom.xml +++ b/page-object/test-automation/pom.xml @@ -33,11 +33,6 @@ test-automation - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -48,4 +43,4 @@ htmlunit - \ No newline at end of file + diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index fa014d6544c7..eb68f4a108e6 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -33,11 +33,6 @@ poison-pill - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/pom.xml b/pom.xml index e83a7c24a210..fef21534fa71 100644 --- a/pom.xml +++ b/pom.xml @@ -236,12 +236,6 @@ camel-stream ${camel.version} - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - junit junit @@ -482,4 +476,4 @@ - \ No newline at end of file + diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index 219709d3119c..e01e81149459 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -33,11 +33,6 @@ private-class-data - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index 3d75f41a99ba..4355df70256c 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -33,11 +33,6 @@ producer-consumer - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/promise/pom.xml b/promise/pom.xml index 7b069c74632e..6c29939d5228 100644 --- a/promise/pom.xml +++ b/promise/pom.xml @@ -33,11 +33,6 @@ promise - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/property/pom.xml b/property/pom.xml index 2df23c88f95f..dc0430fe3f97 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -33,11 +33,6 @@ property - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/prototype/pom.xml b/prototype/pom.xml index 473ba22740a2..ef81d38ecc2a 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -33,11 +33,6 @@ prototype - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/proxy/pom.xml b/proxy/pom.xml index d2d1f552eb1c..aef352a5d23a 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -33,11 +33,6 @@ proxy - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/queue-load-leveling/pom.xml b/queue-load-leveling/pom.xml index 15d81ec6dd94..4b028e3565fe 100644 --- a/queue-load-leveling/pom.xml +++ b/queue-load-leveling/pom.xml @@ -33,11 +33,6 @@ queue-load-leveling - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/reactor/pom.xml b/reactor/pom.xml index f50ff1391ea6..6b561996d623 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -33,11 +33,6 @@ reactor - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index de6e57dc4569..460e58baa287 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -34,11 +34,6 @@ reader-writer-lock - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/repository/pom.xml b/repository/pom.xml index 6b0ab438eba4..36f73e344846 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -54,11 +54,6 @@ com.h2database h2 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index 4c5499f1c43b..17985bdef53a 100644 --- a/resource-acquisition-is-initialization/pom.xml +++ b/resource-acquisition-is-initialization/pom.xml @@ -33,11 +33,6 @@ resource-acquisition-is-initialization - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/retry/pom.xml b/retry/pom.xml index 80a40a45f600..931873491ddd 100644 --- a/retry/pom.xml +++ b/retry/pom.xml @@ -31,11 +31,6 @@ retry jar - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -47,4 +42,4 @@ test - \ No newline at end of file + diff --git a/semaphore/pom.xml b/semaphore/pom.xml index c2c2d19718b4..bebd9b802c56 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -33,11 +33,6 @@ semaphore - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/servant/pom.xml b/servant/pom.xml index 11bfeddd4f5a..e97b3a9895b2 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -33,11 +33,6 @@ servant - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/serverless/pom.xml b/serverless/pom.xml index f3eea887165e..89048283a472 100644 --- a/serverless/pom.xml +++ b/serverless/pom.xml @@ -75,11 +75,6 @@ jackson-annotations ${jackson.version} - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -130,4 +125,4 @@ - \ No newline at end of file + diff --git a/service-layer/pom.xml b/service-layer/pom.xml index 4e22d20d0c34..2bd114c55ca2 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -41,11 +41,6 @@ com.h2database h2 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/service-locator/pom.xml b/service-locator/pom.xml index b4033038a394..fa6fcc4ba470 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -33,11 +33,6 @@ service-locator - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/singleton/pom.xml b/singleton/pom.xml index ac900d0a6d63..e3d8f06e2ea5 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -33,11 +33,6 @@ singleton - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/spatial-partition/pom.xml b/spatial-partition/pom.xml index 40fe0f735634..22eb7a6f68fb 100644 --- a/spatial-partition/pom.xml +++ b/spatial-partition/pom.xml @@ -50,11 +50,6 @@ spatial-partition - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/specification/pom.xml b/specification/pom.xml index 2e250d8ce9a5..8723651051e2 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -33,11 +33,6 @@ specification - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/state/pom.xml b/state/pom.xml index f0433d9b5fa0..9aeb4ec00cbd 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -33,11 +33,6 @@ state - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/step-builder/pom.xml b/step-builder/pom.xml index 42946351dd91..ca5ed709d711 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -34,15 +34,10 @@ step-builder - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine test - \ No newline at end of file + diff --git a/strategy/pom.xml b/strategy/pom.xml index eec6ad9a24ea..a8dbbd007336 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -33,11 +33,6 @@ strategy - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/template-method/pom.xml b/template-method/pom.xml index bd8255a8be45..1345eaa6ca86 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -33,11 +33,6 @@ template-method - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index c4b2cdd282bb..a77230bf2130 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -33,11 +33,6 @@ thread-pool - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/throttling/pom.xml b/throttling/pom.xml index 3f8fac4b6034..d477af53f5aa 100644 --- a/throttling/pom.xml +++ b/throttling/pom.xml @@ -35,11 +35,6 @@ throttling - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -47,4 +42,4 @@ - \ No newline at end of file + diff --git a/tls/pom.xml b/tls/pom.xml index 2303930e2622..d3ccbfc2b79a 100644 --- a/tls/pom.xml +++ b/tls/pom.xml @@ -1,48 +1,43 @@ - - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.21.0-SNAPSHOT - - tls - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.21.0-SNAPSHOT + + tls + + + org.junit.jupiter + junit-jupiter-engine + test + + + diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index 8b4b1bbc53c6..51554d7dce28 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -33,11 +33,6 @@ tolerant-reader - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/trampoline/pom.xml b/trampoline/pom.xml index c5a181dd9f66..338dc101604b 100644 --- a/trampoline/pom.xml +++ b/trampoline/pom.xml @@ -42,11 +42,6 @@ test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/twin/pom.xml b/twin/pom.xml index 0cfc558d7173..74e81ec0df44 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -33,11 +33,6 @@ twin - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index 35d3b966194b..4e66263fefb7 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -36,11 +36,6 @@ json-simple 1.1.1 - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine @@ -52,4 +47,4 @@ test - \ No newline at end of file + diff --git a/value-object/pom.xml b/value-object/pom.xml index 5a942ff3067a..2b951d2a3135 100644 --- a/value-object/pom.xml +++ b/value-object/pom.xml @@ -40,11 +40,6 @@ 19.0 test - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine diff --git a/visitor/pom.xml b/visitor/pom.xml index 779673a23fa1..618b547ea553 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -33,11 +33,6 @@ visitor - - org.junit.jupiter - junit-jupiter-api - test - org.junit.jupiter junit-jupiter-engine From ccb257d5250f15061499dbb63aeba1057bafc963 Mon Sep 17 00:00:00 2001 From: Ranjeet Date: Sun, 4 Aug 2019 19:41:56 +0530 Subject: [PATCH 14/28] fixed bug #883 (#885) --- dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java index 4d72b34da249..827028d09a06 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java @@ -55,9 +55,9 @@ public void run() { final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(new Runnable() { + final World world = new World(); @Override public void run() { - World world = new World(); List countries = world.fetch(); System.out.println("Our world currently has the following countries:-"); for (String country : countries) { From 61ef59de027168c7950592dc31ff969286cdfd64 Mon Sep 17 00:00:00 2001 From: Aravind M Date: Sun, 11 Aug 2019 23:36:27 +0530 Subject: [PATCH 15/28] fix code example containing syntax error (#890) --- ambassador/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ambassador/README.md b/ambassador/README.md index f23d1e13cedb..616604c27e52 100644 --- a/ambassador/README.md +++ b/ambassador/README.md @@ -43,7 +43,7 @@ A remote services represented as a singleton. public class RemoteService implements RemoteServiceInterface { private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class); - private static RemoteService service = null;2 + private static RemoteService service = null; static synchronized RemoteService getRemoteService() { if (service == null) { From 085e47b50dd57be368a3d0baff4af205b2ec3af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 21 Aug 2019 21:47:36 +0300 Subject: [PATCH 16/28] Update SonarCloud badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ef0fbd216b1..c41a48a8898d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Build status](https://travis-ci.org/iluwatar/java-design-patterns.svg?branch=master)](https://travis-ci.org/iluwatar/java-design-patterns) [![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) -[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=com.iluwatar%3Ajava-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard/index/com.iluwatar%3Ajava-design-patterns) +[![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) # Introduction From 11c055055934d1a78e1b98072ea5dd2c4b96da3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 21 Aug 2019 21:51:27 +0300 Subject: [PATCH 17/28] Create .sonarcloud.properties --- .sonarcloud.properties | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .sonarcloud.properties diff --git a/.sonarcloud.properties b/.sonarcloud.properties new file mode 100644 index 000000000000..7a93b07aa76d --- /dev/null +++ b/.sonarcloud.properties @@ -0,0 +1,15 @@ +# Path to sources +#sonar.sources=. +#sonar.exclusions= +#sonar.inclusions= + +# Path to tests +#sonar.tests= +#sonar.test.exclusions= +#sonar.test.inclusions= + +# Source encoding +#sonar.sourceEncoding=UTF-8 + +# Exclusions for copy-paste detection +#sonar.cpd.exclusions= From 7f6067f19fe03c41cc25f704dbdab93b5069f0cb Mon Sep 17 00:00:00 2001 From: Ranjeet Date: Sat, 31 Aug 2019 23:40:35 +0530 Subject: [PATCH 18/28] Added priority queue design pattern (#888) * added priority queue design pattern * Minor Refactored, fixed review comments --- pom.xml | 17 +- priority-queue/README.md | 27 +++ priority-queue/pom.xml | 45 +++++ .../iluwatar/priority/queue/Application.java | 60 ++++++ .../com/iluwatar/priority/queue/Message.java | 50 +++++ .../priority/queue/PriorityMessageQueue.java | 178 ++++++++++++++++++ .../iluwatar/priority/queue/QueueManager.java | 57 ++++++ .../com/iluwatar/priority/queue/Worker.java | 63 +++++++ .../queue/PriorityMessageQueueTest.java | 73 +++++++ .../priority/queue/QueueManagerTest.java | 53 ++++++ 10 files changed, 616 insertions(+), 7 deletions(-) create mode 100644 priority-queue/README.md create mode 100644 priority-queue/pom.xml create mode 100644 priority-queue/src/main/java/com/iluwatar/priority/queue/Application.java create mode 100644 priority-queue/src/main/java/com/iluwatar/priority/queue/Message.java create mode 100644 priority-queue/src/main/java/com/iluwatar/priority/queue/PriorityMessageQueue.java create mode 100644 priority-queue/src/main/java/com/iluwatar/priority/queue/QueueManager.java create mode 100644 priority-queue/src/main/java/com/iluwatar/priority/queue/Worker.java create mode 100644 priority-queue/src/test/java/com/iluwatar/priority/queue/PriorityMessageQueueTest.java create mode 100644 priority-queue/src/test/java/com/iluwatar/priority/queue/QueueManagerTest.java diff --git a/pom.xml b/pom.xml index fef21534fa71..f305e97d983e 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,9 @@ 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. ---> +--> + 4.0.0 com.iluwatar java-design-patterns @@ -162,12 +164,13 @@ trampoline serverless ambassador - acyclic-visitor - collection-pipeline - master-worker-pattern - spatial-partition - commander - typeobjectpattern + acyclic-visitor + collection-pipeline + master-worker-pattern + spatial-partition + priority-queue + commander + typeobjectpattern diff --git a/priority-queue/README.md b/priority-queue/README.md new file mode 100644 index 000000000000..bc8d7b8cfed0 --- /dev/null +++ b/priority-queue/README.md @@ -0,0 +1,27 @@ +--- +layout: pattern +title: Priority Queue Pattern +folder: priority-queue +permalink: /patterns/priority-queue/ +categories: Behavioral +tags: + - Java + - Difficulty-Beginner +--- + +## Intent +Prioritize requests sent to services so that requests with a higher priority are received and processed more quickly than those of a lower priority. This pattern is useful in applications that offer different service level guarantees to individual clients. + +## Explanation +Applications may delegate specific tasks to other services; for example, to perform background processing or to integrate with other applications or services. In the cloud, a message queue is typically used to delegate tasks to background processing. In many cases the order in which requests are received by a service is not important. However, in some cases it may be necessary to prioritize specific requests. These requests should be processed earlier than others of a lower priority that may have been sent previously by the application. + +## Applicability +Use the Property pattern when + +* The system must handle multiple tasks that might have different priorities. +* Different users or tenants should be served with different priority.. + +## Real world examples + +* [ Priority Queue Pattern](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589794(v=pandp.10)) +Microsoft Azure does not provide a queuing mechanism that natively support automatic prioritization of messages through sorting. However, it does provide Azure Service Bus topics and subscriptions, which support a queuing mechanism that provides message filtering, together with a wide range of flexible capabilities that make it ideal for use in almost all priority queue implementations. diff --git a/priority-queue/pom.xml b/priority-queue/pom.xml new file mode 100644 index 000000000000..9e5a788066c3 --- /dev/null +++ b/priority-queue/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + priority-queue + + com.iluwatar + java-design-patterns + 1.21.0-SNAPSHOT + + + + + org.junit.jupiter + junit-jupiter-engine + test + + + + \ No newline at end of file diff --git a/priority-queue/src/main/java/com/iluwatar/priority/queue/Application.java b/priority-queue/src/main/java/com/iluwatar/priority/queue/Application.java new file mode 100644 index 000000000000..5ec1dc0cbaae --- /dev/null +++ b/priority-queue/src/main/java/com/iluwatar/priority/queue/Application.java @@ -0,0 +1,60 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +/** + * Prioritize requests sent to services so that requests with a higher priority are received and + * processed more quickly than those of a lower priority. + * This pattern is useful in applications that offer different service level guarantees + * to individual clients. + * Example :Send multiple message with different priority to worker queue. + * Worker execute higher priority message first + * @see "https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589794(v=pandp.10)" + */ +public class Application { + /** + * main entry + */ + public static void main(String[] args) throws Exception { + + QueueManager queueManager = new QueueManager(100); + + // push some message to queue + // Low Priority message + for (int i = 0; i < 100; i++) { + queueManager.publishMessage(new Message("Low Message Priority", 0)); + } + + // High Priority message + for (int i = 0; i < 100; i++) { + queueManager.publishMessage(new Message("High Message Priority", 1)); + } + + + // run worker + Worker worker = new Worker(queueManager); + worker.run(); + + + } +} diff --git a/priority-queue/src/main/java/com/iluwatar/priority/queue/Message.java b/priority-queue/src/main/java/com/iluwatar/priority/queue/Message.java new file mode 100644 index 000000000000..66c561d64269 --- /dev/null +++ b/priority-queue/src/main/java/com/iluwatar/priority/queue/Message.java @@ -0,0 +1,50 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +/** + * Message bean + */ +public class Message implements Comparable { + private final String message; + private final int priority; // define message priority in queue + + + public Message(String message, int priority) { + this.message = message; + this.priority = priority; + } + + @Override + public int compareTo(Message o) { + return priority - o.priority; + } + + @Override + public String toString() { + return "Message{" + + "message='" + message + '\'' + + ", priority=" + priority + + '}'; + } +} diff --git a/priority-queue/src/main/java/com/iluwatar/priority/queue/PriorityMessageQueue.java b/priority-queue/src/main/java/com/iluwatar/priority/queue/PriorityMessageQueue.java new file mode 100644 index 000000000000..2a49d94b53e3 --- /dev/null +++ b/priority-queue/src/main/java/com/iluwatar/priority/queue/PriorityMessageQueue.java @@ -0,0 +1,178 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static java.util.Arrays.copyOf; + +/** + * Keep high Priority message on top using maxHeap. + * + * @param : DataType to push in Queue + */ +public class PriorityMessageQueue { + + private static final Logger LOGGER = LoggerFactory.getLogger(PriorityMessageQueue.class); + + private int size = 0; + + private int capacity; + + + private T[] queue; + + public PriorityMessageQueue(T[] queue) { + this.queue = queue; + this.capacity = queue.length; + } + + /** + * Remove top message from queue + */ + public T remove() { + if (isEmpty()) { + return null; + } + + T root = queue[0]; + queue[0] = queue[size - 1]; + size--; + maxHeapifyDown(); + return root; + } + + /** + * Add message to queue + */ + public void add(T t) { + ensureCapacity(); + queue[size] = t; + size++; + maxHeapifyUp(); + } + + /** + * Check queue size + */ + public boolean isEmpty() { + return size == 0; + } + + + private void maxHeapifyDown() { + int index = 0; + while (hasLeftChild(index)) { + + int smallerIndex = leftChildIndex(index); + + if (hasRightChild(index) && right(index).compareTo(left(index)) > 0) { + smallerIndex = rightChildIndex(index); + } + + if (queue[index].compareTo(queue[smallerIndex]) > 0) { + break; + } else { + swap(index, smallerIndex); + } + + index = smallerIndex; + + + } + + } + + private void maxHeapifyUp() { + int index = size - 1; + while (hasParent(index) && parent(index).compareTo(queue[index]) < 0) { + swap(parentIndex(index), index); + index = parentIndex(index); + } + } + + + // index + private int parentIndex(int pos) { + return (pos - 1) / 2; + } + + private int leftChildIndex(int parentPos) { + return 2 * parentPos + 1; + } + + private int rightChildIndex(int parentPos) { + return 2 * parentPos + 2; + } + + // value + private T parent(int childIndex) { + return queue[parentIndex(childIndex)]; + } + + private T left(int parentIndex) { + return queue[leftChildIndex(parentIndex)]; + } + + private T right(int parentIndex) { + return queue[rightChildIndex(parentIndex)]; + } + + // check + private boolean hasLeftChild(int index) { + return leftChildIndex(index) < size; + } + + private boolean hasRightChild(int index) { + return rightChildIndex(index) < size; + } + + private boolean hasParent(int index) { + return parentIndex(index) >= 0; + } + + private void swap(int fpos, int tpos) { + T tmp = queue[fpos]; + queue[fpos] = queue[tpos]; + queue[tpos] = tmp; + } + + private void ensureCapacity() { + if (size == capacity) { + capacity = capacity * 2; + queue = copyOf(queue, capacity); + } + } + + /** + * For debug .. print current state of queue + */ + public void print() { + for (int i = 0; i <= size / 2; i++) { + LOGGER.info(" PARENT : " + queue[i] + " LEFT CHILD : " + + left(i) + " RIGHT CHILD :" + right(i)); + } + } + +} diff --git a/priority-queue/src/main/java/com/iluwatar/priority/queue/QueueManager.java b/priority-queue/src/main/java/com/iluwatar/priority/queue/QueueManager.java new file mode 100644 index 000000000000..7eb68500b178 --- /dev/null +++ b/priority-queue/src/main/java/com/iluwatar/priority/queue/QueueManager.java @@ -0,0 +1,57 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +/** + * Manage priority queue + */ +public class QueueManager { + /* + Priority message + */ + private final PriorityMessageQueue messagePriorityMessageQueue; + + public QueueManager(int initialCapacity) { + messagePriorityMessageQueue = new PriorityMessageQueue(new Message[initialCapacity]); + } + + /** + * Publish message to queue + */ + public void publishMessage(Message message) { + messagePriorityMessageQueue.add(message); + } + + + /** + * recive message from queue + */ + public Message receiveMessage() { + if (messagePriorityMessageQueue.isEmpty()) { + return null; + } + return messagePriorityMessageQueue.remove(); + } + + +} diff --git a/priority-queue/src/main/java/com/iluwatar/priority/queue/Worker.java b/priority-queue/src/main/java/com/iluwatar/priority/queue/Worker.java new file mode 100644 index 000000000000..22faa1519e34 --- /dev/null +++ b/priority-queue/src/main/java/com/iluwatar/priority/queue/Worker.java @@ -0,0 +1,63 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Message Worker + */ +public class Worker { + + private static final Logger LOGGER = LoggerFactory.getLogger(Worker.class); + + private final QueueManager queueManager; + + public Worker(QueueManager queueManager) { + this.queueManager = queueManager; + } + + /** + * Keep checking queue for message + */ + public void run() throws Exception { + while (true) { + Message message = queueManager.receiveMessage(); + if (message == null) { + LOGGER.info("No Message ... waiting"); + Thread.sleep(200); + } else { + processMessage(message); + } + } + } + + /** + * Process message + */ + private void processMessage(Message message) { + LOGGER.info(message.toString()); + } + +} diff --git a/priority-queue/src/test/java/com/iluwatar/priority/queue/PriorityMessageQueueTest.java b/priority-queue/src/test/java/com/iluwatar/priority/queue/PriorityMessageQueueTest.java new file mode 100644 index 000000000000..6dc26fcf67e2 --- /dev/null +++ b/priority-queue/src/test/java/com/iluwatar/priority/queue/PriorityMessageQueueTest.java @@ -0,0 +1,73 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Test case for order of messages + */ +public class PriorityMessageQueueTest { + + + @Test + public void remove() { + PriorityMessageQueue stringPriorityMessageQueue = new PriorityMessageQueue<>(new String[2]); + String pushMessage = "test"; + stringPriorityMessageQueue.add(pushMessage); + assertEquals(stringPriorityMessageQueue.remove(), pushMessage); + } + + @Test + public void add() { + PriorityMessageQueue stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]); + stringPriorityMessageQueue.add(1); + stringPriorityMessageQueue.add(5); + stringPriorityMessageQueue.add(10); + stringPriorityMessageQueue.add(3); + assertTrue(stringPriorityMessageQueue.remove() == 10); + } + + @Test + public void isEmpty() { + PriorityMessageQueue stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]); + assertTrue(stringPriorityMessageQueue.isEmpty()); + stringPriorityMessageQueue.add(1); + stringPriorityMessageQueue.remove(); + assertTrue(stringPriorityMessageQueue.isEmpty()); + } + + @Test + public void testEnsureSize() { + PriorityMessageQueue stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]); + assertTrue(stringPriorityMessageQueue.isEmpty()); + stringPriorityMessageQueue.add(1); + stringPriorityMessageQueue.add(2); + stringPriorityMessageQueue.add(2); + stringPriorityMessageQueue.add(3); + assertTrue(stringPriorityMessageQueue.remove() == 3); + } +} \ No newline at end of file diff --git a/priority-queue/src/test/java/com/iluwatar/priority/queue/QueueManagerTest.java b/priority-queue/src/test/java/com/iluwatar/priority/queue/QueueManagerTest.java new file mode 100644 index 000000000000..721fea4deea1 --- /dev/null +++ b/priority-queue/src/test/java/com/iluwatar/priority/queue/QueueManagerTest.java @@ -0,0 +1,53 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.priority.queue; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Check queue manager + */ +public class QueueManagerTest { + + @Test + public void publishMessage() { + QueueManager queueManager = new QueueManager(2); + Message testMessage = new Message("Test Message", 1); + queueManager.publishMessage(testMessage); + Message recivedMessage = queueManager.receiveMessage(); + assertEquals(testMessage, recivedMessage); + } + + @Test + public void receiveMessage() { + QueueManager queueManager = new QueueManager(2); + Message testMessage1 = new Message("Test Message 1", 1); + queueManager.publishMessage(testMessage1); + Message testMessage2 = new Message("Test Message 2", 2); + queueManager.publishMessage(testMessage2); + Message recivedMessage = queueManager.receiveMessage(); + assertEquals(testMessage2, recivedMessage); + } +} \ No newline at end of file From 318f811fead95c4a363d776e968b0b1a4a112c86 Mon Sep 17 00:00:00 2001 From: Pawel Zawitowski Date: Tue, 3 Sep 2019 20:50:48 +0200 Subject: [PATCH 19/28] Bytecode pattern #553 (#896) * Added bytecode pattern * Diagram changed and added licence information * Added bytecode module to main pom. * Fixed missing dependency error --- bytecode/README.md | 25 +++ bytecode/etc/bytecode.png | Bin 0 -> 19866 bytes bytecode/etc/bytecode.ucls | 49 ++++++ bytecode/pom.xml | 45 +++++ .../main/java/com/iluwatar/bytecode/App.java | 79 +++++++++ .../com/iluwatar/bytecode/Instruction.java | 65 ++++++++ .../com/iluwatar/bytecode/VirtualMachine.java | 142 ++++++++++++++++ .../java/com/iluwatar/bytecode/Wizard.java | 83 ++++++++++ .../util/InstructionConverterUtil.java | 76 +++++++++ .../java/com/iluwatar/bytecode/AppTest.java | 37 +++++ .../iluwatar/bytecode/VirtualMachineTest.java | 154 ++++++++++++++++++ .../util/InstructionConverterUtilTest.java | 63 +++++++ pom.xml | 1 + 13 files changed, 819 insertions(+) create mode 100644 bytecode/README.md create mode 100644 bytecode/etc/bytecode.png create mode 100644 bytecode/etc/bytecode.ucls create mode 100644 bytecode/pom.xml create mode 100644 bytecode/src/main/java/com/iluwatar/bytecode/App.java create mode 100644 bytecode/src/main/java/com/iluwatar/bytecode/Instruction.java create mode 100644 bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java create mode 100644 bytecode/src/main/java/com/iluwatar/bytecode/Wizard.java create mode 100644 bytecode/src/main/java/com/iluwatar/bytecode/util/InstructionConverterUtil.java create mode 100644 bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java create mode 100644 bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java create mode 100644 bytecode/src/test/java/com/iluwatar/bytecode/util/InstructionConverterUtilTest.java diff --git a/bytecode/README.md b/bytecode/README.md new file mode 100644 index 000000000000..d2fc45e1e2d1 --- /dev/null +++ b/bytecode/README.md @@ -0,0 +1,25 @@ +--- +layout: pattern +title: Bytecode +folder: bytecode +permalink: /patterns/bytecode/ +categories: Behavioral +tags: + - Java + - Difficulty-Beginner +--- + +## Intent +Allows to encode behaviour as instructions for virtual machine. + +## Applicability +Use the Bytecode pattern when you have a lot of behavior you need to define and your +game’s implementation language isn’t a good fit because: + +* it’s too low-level, making it tedious or error-prone to program in. +* iterating on it takes too long due to slow compile times or other tooling issues. +* it has too much trust. If you want to ensure the behavior being defined can’t break the game, you need to sandbox it from the rest of the codebase. + +## Credits + +* [Game programming patterns](http://gameprogrammingpatterns.com/bytecode.html) diff --git a/bytecode/etc/bytecode.png b/bytecode/etc/bytecode.png new file mode 100644 index 0000000000000000000000000000000000000000..31b6bc6edba64cfb51910e5d2c5322be46e7c075 GIT binary patch literal 19866 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

`G1h3pdcwAMtsKKi=qQrS$#qHo8o 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 D@r6J8 literal 0 HcmV?d00001 diff --git a/bytecode/etc/bytecode.ucls b/bytecode/etc/bytecode.ucls new file mode 100644 index 000000000000..3ec390458956 --- /dev/null +++ b/bytecode/etc/bytecode.ucls @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bytecode/pom.xml b/bytecode/pom.xml new file mode 100644 index 000000000000..e9e6247f8eb2 --- /dev/null +++ b/bytecode/pom.xml @@ -0,0 +1,45 @@ + + + + + java-design-patterns + com.iluwatar + 1.21.0-SNAPSHOT + + 4.0.0 + + bytecode + + + org.junit.jupiter + junit-jupiter-engine + test + + + + \ No newline at end of file diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/App.java b/bytecode/src/main/java/com/iluwatar/bytecode/App.java new file mode 100644 index 000000000000..90b97bd33308 --- /dev/null +++ b/bytecode/src/main/java/com/iluwatar/bytecode/App.java @@ -0,0 +1,79 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +import com.iluwatar.bytecode.util.InstructionConverterUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The intention of Bytecode pattern is to give behavior the flexibility of data by encoding it as instructions + * for a virtual machine. + * An instruction set defines the low-level operations that can be performed. A series of instructions is encoded as + * a sequence of bytes. A virtual machine executes these instructions one at a time, + * using a stack for intermediate values. By combining instructions, complex high-level behavior can be defined. + * + * This pattern should be used when there is a need to define high number of behaviours and implementation engine + * is not a good choice because + * It is too lowe level + * Iterating on it takes too long due to slow compile times or other tooling issues. + * It has too much trust. If you want to ensure the behavior being defined can’t break the game, + * you need to sandbox it from the rest of the codebase. + * + */ +public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * Main app method + * @param args command line args + */ + public static void main(String[] args) { + VirtualMachine vm = new VirtualMachine(); + + Wizard wizard = new Wizard(); + wizard.setHealth(45); + wizard.setAgility(7); + wizard.setWisdom(11); + vm.getWizards()[0] = wizard; + + interpretInstruction("LITERAL 0", vm); + interpretInstruction( "LITERAL 0", vm); + interpretInstruction( "GET_HEALTH", vm); + interpretInstruction( "LITERAL 0", vm); + interpretInstruction( "GET_AGILITY", vm); + interpretInstruction( "LITERAL 0", vm); + interpretInstruction( "GET_WISDOM ", vm); + interpretInstruction( "ADD", vm); + interpretInstruction( "LITERAL 2", vm); + interpretInstruction( "DIVIDE", vm); + interpretInstruction( "ADD", vm); + interpretInstruction( "SET_HEALTH", vm); + } + + private static void interpretInstruction(String instruction, VirtualMachine vm) { + InstructionConverterUtil converter = new InstructionConverterUtil(); + vm.execute(converter.convertToByteCode(instruction)); + LOGGER.info(instruction + String.format("%" + (12 - instruction.length()) + "s", "" ) + vm.getStack()); + } +} diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/Instruction.java b/bytecode/src/main/java/com/iluwatar/bytecode/Instruction.java new file mode 100644 index 000000000000..2ceb66e3bdc2 --- /dev/null +++ b/bytecode/src/main/java/com/iluwatar/bytecode/Instruction.java @@ -0,0 +1,65 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +/** + * Representation of instructions understandable by virtual machine + */ +public enum Instruction { + + LITERAL(1), + SET_HEALTH(2), + SET_WISDOM (3), + SET_AGILITY(4), + PLAY_SOUND(5), + SPAWN_PARTICLES(6), + GET_HEALTH(7), + GET_AGILITY(8), + GET_WISDOM(9), + ADD(10), + DIVIDE (11); + + private int value; + + Instruction(int value) { + this.value = value; + } + + public int getIntValue() { + return value; + } + + /** + * Converts integer value to Instruction + * @param value value of instruction + * @return representation of the instruction + */ + public static Instruction getInstruction(int value) { + for (int i = 0; i < Instruction.values().length; i++) { + if (Instruction.values()[i].getIntValue() == value) { + return Instruction.values()[i]; + } + } + throw new IllegalArgumentException("Invalid instruction value"); + } +} diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java new file mode 100644 index 000000000000..aedafe514dce --- /dev/null +++ b/bytecode/src/main/java/com/iluwatar/bytecode/VirtualMachine.java @@ -0,0 +1,142 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +import java.util.Stack; + +/** + * Implementation of virtual machine + */ +public class VirtualMachine { + + private Stack stack = new Stack(); + + private Wizard[] wizards = new Wizard[2]; + + /** + * Constructor + */ + public VirtualMachine() { + for (int i = 0; i < wizards.length; i++) { + wizards[i] = new Wizard(); + } + } + + /** + * Executes provided bytecode + * @param bytecode to execute + */ + public void execute(int[] bytecode) { + for (int i = 0; i < bytecode.length; i++) { + Instruction instruction = Instruction.getInstruction(bytecode[i]); + int wizard; + int amount; + switch (instruction) { + case LITERAL: + // Read the next byte from the bytecode. + int value = bytecode[++i]; + stack.push(value); + break; + case SET_AGILITY: + amount = stack.pop(); + wizard = stack.pop(); + setAgility(wizard, amount); + break; + case SET_WISDOM: + amount = stack.pop(); + wizard = stack.pop(); + setWisdom(wizard, amount); + break; + case SET_HEALTH: + amount = stack.pop(); + wizard = stack.pop(); + setHealth(wizard, amount); + break; + case GET_HEALTH: + wizard = stack.pop(); + stack.push(getHealth(wizard)); + break; + case GET_AGILITY: + wizard = stack.pop(); + stack.push(getAgility(wizard)); + break; + case GET_WISDOM: + wizard = stack.pop(); + stack.push(getWisdom(wizard)); + break; + case ADD: + int a = stack.pop(); + int b = stack.pop(); + stack.push(a + b); + break; + case DIVIDE: + a = stack.pop(); + b = stack.pop(); + stack.push(b / a); + break; + case PLAY_SOUND: + wizard = stack.pop(); + getWizards()[wizard].playSound(); + break; + case SPAWN_PARTICLES: + wizard = stack.pop(); + getWizards()[wizard].spawnParticles(); + break; + default: + throw new IllegalArgumentException("Invalid instruction value"); + } + } + } + + public Stack getStack() { + return stack; + } + + public void setHealth(int wizard, int amount) { + wizards[wizard].setHealth(amount); + } + + public void setWisdom(int wizard, int amount) { + wizards[wizard].setWisdom(amount); + } + + public void setAgility(int wizard, int amount) { + wizards[wizard].setAgility(amount); + } + + public int getHealth(int wizard) { + return wizards[wizard].getHealth(); + } + + public int getWisdom(int wizard) { + return wizards[wizard].getWisdom(); + } + + public int getAgility(int wizard) { + return wizards[wizard].getAgility(); + } + + public Wizard[] getWizards() { + return wizards; + } +} diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/Wizard.java b/bytecode/src/main/java/com/iluwatar/bytecode/Wizard.java new file mode 100644 index 000000000000..ca47fd28f873 --- /dev/null +++ b/bytecode/src/main/java/com/iluwatar/bytecode/Wizard.java @@ -0,0 +1,83 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class represent game objects which properties can be changed by instructions interpreted by virtual machine + */ +public class Wizard { + private static final Logger LOGGER = LoggerFactory.getLogger(Wizard.class); + + private int health; + + private int agility; + private int wisdom; + + private int numberOfPlayedSounds; + private int numberOfSpawnedParticles; + + public int getHealth() { + return health; + } + + public void setHealth(int health) { + this.health = health; + } + + public int getAgility() { + return agility; + } + + public void setAgility(int agility) { + this.agility = agility; + } + + public int getWisdom() { + return wisdom; + } + + public void setWisdom(int wisdom) { + this.wisdom = wisdom; + } + + public void playSound() { + LOGGER.info("Playing sound"); + numberOfPlayedSounds++; + } + + public void spawnParticles() { + LOGGER.info("Spawning particles"); + numberOfSpawnedParticles++; + } + + public int getNumberOfPlayedSounds() { + return numberOfPlayedSounds; + } + + public int getNumberOfSpawnedParticles() { + return numberOfSpawnedParticles; + } +} diff --git a/bytecode/src/main/java/com/iluwatar/bytecode/util/InstructionConverterUtil.java b/bytecode/src/main/java/com/iluwatar/bytecode/util/InstructionConverterUtil.java new file mode 100644 index 000000000000..202784d5a96c --- /dev/null +++ b/bytecode/src/main/java/com/iluwatar/bytecode/util/InstructionConverterUtil.java @@ -0,0 +1,76 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode.util; + +import com.iluwatar.bytecode.Instruction; + +/** + * Utility class used for instruction validation and conversion + */ +public class InstructionConverterUtil { + /** + * Converts instructions represented as String + * + * @param instructions to convert + * @return array of int representing bytecode + */ + public static int[] convertToByteCode(String instructions) { + if (instructions == null || instructions.trim().length() == 0) { + return new int[0]; + } + + String[] splitedInstructions = instructions.trim().split(" "); + int[] bytecode = new int[splitedInstructions.length]; + for (int i = 0; i < splitedInstructions.length; i++) { + if (isValidInstruction(splitedInstructions[i])) { + bytecode[i] = Instruction.valueOf(splitedInstructions[i]).getIntValue(); + } else if (isValidInt(splitedInstructions[i])) { + bytecode[i] = Integer.valueOf(splitedInstructions[i]); + } else { + throw new IllegalArgumentException("Invalid instruction or number: " + splitedInstructions[i]); + } + } + + return bytecode; + } + + private static boolean isValidInstruction(String instruction) { + try { + Instruction.valueOf(instruction); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + private static boolean isValidInt(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + +} diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java new file mode 100644 index 000000000000..014ec787569c --- /dev/null +++ b/bytecode/src/test/java/com/iluwatar/bytecode/AppTest.java @@ -0,0 +1,37 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +import org.junit.jupiter.api.Test; + +/** + * Application test + */ +public class AppTest { + + @Test + public void test() { + String[] args = {}; + App.main(args); + } +} diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java new file mode 100644 index 000000000000..e4379c9ede38 --- /dev/null +++ b/bytecode/src/test/java/com/iluwatar/bytecode/VirtualMachineTest.java @@ -0,0 +1,154 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode; + +import org.junit.jupiter.api.Test; + +import static com.iluwatar.bytecode.Instruction.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Test for {@Link VirtualMachine} + */ +public class VirtualMachineTest { + + @Test + public void testLiteral() { + int[] bytecode = new int[2]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = 10; + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(1, vm.getStack().size()); + assertEquals(Integer.valueOf(10), vm.getStack().pop()); + } + + @Test + public void testSetHealth() { + int wizardNumber = 0; + int[] bytecode = new int[5]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = LITERAL.getIntValue(); + bytecode[3] = 50; // health amount + bytecode[4] = SET_HEALTH.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(50, vm.getWizards()[wizardNumber].getHealth()); + } + + @Test + public void testSetAgility() { + int wizardNumber = 0; + int[] bytecode = new int[5]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = LITERAL.getIntValue(); + bytecode[3] = 50; // agility amount + bytecode[4] = SET_AGILITY.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(50, vm.getWizards()[wizardNumber].getAgility()); + } + + @Test + public void testSetWisdom() { + int wizardNumber = 0; + int[] bytecode = new int[5]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = LITERAL.getIntValue(); + bytecode[3] = 50; // wisdom amount + bytecode[4] = SET_WISDOM.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(50, vm.getWizards()[wizardNumber].getWisdom()); + } + + @Test + public void testGetHealth() { + int wizardNumber = 0; + int[] bytecode = new int[8]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = LITERAL.getIntValue(); + bytecode[3] = 50; // health amount + bytecode[4] = SET_HEALTH.getIntValue(); + bytecode[5] = LITERAL.getIntValue();; + bytecode[6] = wizardNumber; + bytecode[7] = GET_HEALTH.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(Integer.valueOf(50), vm.getStack().pop()); + } + + @Test + public void testPlaySound() { + int wizardNumber = 0; + int[] bytecode = new int[3]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = PLAY_SOUND.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(0, vm.getStack().size()); + assertEquals(1, vm.getWizards()[0].getNumberOfPlayedSounds()); + } + + @Test + public void testSpawnParticles() { + int wizardNumber = 0; + int[] bytecode = new int[3]; + bytecode[0] = LITERAL.getIntValue(); + bytecode[1] = wizardNumber; + bytecode[2] = SPAWN_PARTICLES.getIntValue(); + + VirtualMachine vm = new VirtualMachine(); + vm.execute(bytecode); + + assertEquals(0, vm.getStack().size()); + assertEquals(1, vm.getWizards()[0].getNumberOfSpawnedParticles()); + } + + @Test + public void testInvalidInstruction() { + int[] bytecode = new int[1]; + bytecode[0] = 999; + VirtualMachine vm = new VirtualMachine(); + + assertThrows(IllegalArgumentException.class, () -> vm.execute(bytecode)); + } +} diff --git a/bytecode/src/test/java/com/iluwatar/bytecode/util/InstructionConverterUtilTest.java b/bytecode/src/test/java/com/iluwatar/bytecode/util/InstructionConverterUtilTest.java new file mode 100644 index 000000000000..4743ac109e12 --- /dev/null +++ b/bytecode/src/test/java/com/iluwatar/bytecode/util/InstructionConverterUtilTest.java @@ -0,0 +1,63 @@ +/** + * The MIT License + * Copyright (c) 2014 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.iluwatar.bytecode.util; + +import com.iluwatar.bytecode.Instruction; +import com.iluwatar.bytecode.util.InstructionConverterUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test for {@Link InstructionConverterUtil} + */ +public class InstructionConverterUtilTest { + @Test + public void testEmptyInstruction() { + String instruction = ""; + + int[] bytecode = InstructionConverterUtil.convertToByteCode(instruction); + + Assertions.assertEquals(0, bytecode.length); + } + + @Test + public void testInstructions() { + String instructions = + "LITERAL 35 SET_HEALTH SET_WISDOM SET_AGILITY PLAY_SOUND SPAWN_PARTICLES GET_HEALTH ADD DIVIDE"; + + int[] bytecode = InstructionConverterUtil.convertToByteCode(instructions); + + Assertions.assertEquals(10, bytecode.length); + Assertions.assertEquals(Instruction.LITERAL.getIntValue(), bytecode[0]); + Assertions.assertEquals(35, bytecode[1]); + Assertions.assertEquals(Instruction.SET_HEALTH.getIntValue(), bytecode[2]); + Assertions.assertEquals(Instruction.SET_WISDOM.getIntValue(), bytecode[3]); + Assertions.assertEquals(Instruction.SET_AGILITY.getIntValue(), bytecode[4]); + Assertions.assertEquals(Instruction.PLAY_SOUND.getIntValue(), bytecode[5]); + Assertions.assertEquals(Instruction.SPAWN_PARTICLES.getIntValue(), bytecode[6]); + Assertions.assertEquals(Instruction.GET_HEALTH.getIntValue(), bytecode[7]); + Assertions.assertEquals(Instruction.ADD.getIntValue(), bytecode[8]); + Assertions.assertEquals(Instruction.DIVIDE.getIntValue(), bytecode[9]); + } + +} diff --git a/pom.xml b/pom.xml index f305e97d983e..c55ed6492211 100644 --- a/pom.xml +++ b/pom.xml @@ -171,6 +171,7 @@ priority-queue commander typeobjectpattern + bytecode From 35dc25d4806f898bfc8f1ee31e4c9479bcc496d8 Mon Sep 17 00:00:00 2001 From: saksham93 <37399540+saksham93@users.noreply.github.com> Date: Sat, 7 Sep 2019 21:24:40 +0400 Subject: [PATCH 20/28] MInor bug fix Issue #895 -> Code comment change (https://github.com/iluwatar/java-design-patterns/issues/895) (#901) --- .../src/main/java/com/iluwatar/acyclicvisitor/App.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/App.java b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/App.java index 06e4bd2f255d..2a2f64591b6c 100644 --- a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/App.java +++ b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/App.java @@ -47,7 +47,7 @@ public static void main(String[] args) { Zoom zoom = new Zoom(); Hayes hayes = new Hayes(); - hayes.accept(conDos); // Hayes modem with Unix configurator + hayes.accept(conDos); // Hayes modem with Dos configurator zoom.accept(conDos); // Zoom modem with Dos configurator hayes.accept(conUnix); // Hayes modem with Unix configurator zoom.accept(conUnix); // Zoom modem with Unix configurator From c653edf38fae9f067b1a35bfaf376b3312d97ee8 Mon Sep 17 00:00:00 2001 From: dongshengchen Date: Sun, 8 Sep 2019 01:52:49 +0800 Subject: [PATCH 21/28] fix must override a superclass method (#919) * fix must override a superclass method * fix must override a superclass method --- .../java/com/iluwatar/abstractfactory/ElfKingdomFactory.java | 3 +++ .../java/com/iluwatar/abstractfactory/OrcKingdomFactory.java | 3 +++ .../com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java | 2 ++ .../com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java | 1 + .../main/java/com/iluwatar/factory/method/ElfBlacksmith.java | 1 + .../main/java/com/iluwatar/factory/method/OrcBlacksmith.java | 1 + .../java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java | 1 + 7 files changed, 12 insertions(+) diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java index 31cfddb70ff8..fc71ded766d6 100644 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java +++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java @@ -29,14 +29,17 @@ */ public class ElfKingdomFactory implements KingdomFactory { + @Override public Castle createCastle() { return new ElfCastle(); } + @Override public King createKing() { return new ElfKing(); } + @Override public Army createArmy() { return new ElfArmy(); } diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java index 5b2ba3a30fc9..43eef13a111b 100644 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java +++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java @@ -29,14 +29,17 @@ */ public class OrcKingdomFactory implements KingdomFactory { + @Override public Castle createCastle() { return new OrcCastle(); } + @Override public King createKing() { return new OrcKing(); } + @Override public Army createArmy() { return new OrcArmy(); } diff --git a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java index a6d66b1db477..4ef69b4b772b 100644 --- a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java +++ b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java @@ -33,10 +33,12 @@ public class ConfigureForDosVisitor implements AllModemVisitor { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class); + @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."); } diff --git a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java index c3546012166d..f3be302f734c 100644 --- a/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java +++ b/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java @@ -34,6 +34,7 @@ public class ConfigureForUnixVisitor implements ZoomVisitor { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForUnixVisitor.class); + @Override public void visit(Zoom zoom) { LOGGER.info(zoom + " used with Unix configurator."); } 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 66938bb1773b..63e083e3501d 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 @@ -29,6 +29,7 @@ */ public class ElfBlacksmith implements Blacksmith { + @Override public Weapon manufactureWeapon(WeaponType weaponType) { return new ElfWeapon(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 e2921a4b52cf..6df398a814e9 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 @@ -29,6 +29,7 @@ */ public class OrcBlacksmith implements Blacksmith { + @Override public Weapon manufactureWeapon(WeaponType weaponType) { return new OrcWeapon(weaponType); } diff --git a/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java b/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java index 3d1e68287ccd..e2da42350bdd 100644 --- a/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java +++ b/throttling/src/main/java/com/iluwatar/throttling/timer/ThrottleTimerImpl.java @@ -49,6 +49,7 @@ public ThrottleTimerImpl(int throttlePeriod, CallsCount callsCount) { * A timer is initiated with this method. The timer runs every second and resets the * counter. */ + @Override public void start() { new Timer(true).schedule(new TimerTask() { @Override From 8c865e6b4dace244042c8b3c4399d81adcffdf90 Mon Sep 17 00:00:00 2001 From: Ibrahim ali abdelghany Date: Sat, 7 Sep 2019 20:07:01 +0200 Subject: [PATCH 22/28] clean code (#910) --- .../com/iluwatar/abstractdocument/AbstractDocument.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java b/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java index 36a946cc9eca..fccc23d83b7b 100644 --- a/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java +++ b/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java @@ -54,17 +54,16 @@ public Object get(String key) { @Override public Stream children(String key, Function, T> constructor) { - Optional>> any = Stream.of(get(key)).filter(el -> el != null) + Optional>> any = Stream.of(get(key)).filter(Objects::nonNull) .map(el -> (List>) el).findAny(); - return any.isPresent() ? any.get().stream().map(constructor) : Stream.empty(); + return any.map(maps -> maps.stream().map(constructor)).orElseGet(Stream::empty); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(getClass().getName()).append("["); - properties.entrySet() - .forEach(e -> builder.append("[").append(e.getKey()).append(" : ").append(e.getValue()).append("]")); + properties.forEach((key, value) -> builder.append("[").append(key).append(" : ").append(value).append("]")); builder.append("]"); return builder.toString(); } From f1410337b570c6d444e98713036d13b53bdefe68 Mon Sep 17 00:00:00 2001 From: Adrian Yao Date: Sun, 8 Sep 2019 02:13:15 +0800 Subject: [PATCH 23/28] Fix issue #761: ThreadSafeDoubleCheckLocking.java: Instantiating by Reflection call will be successful if you do that firstly (#920) --- singleton/pom.xml | 4 ++++ .../singleton/ThreadSafeDoubleCheckLocking.java | 6 +++++- .../ThreadSafeDoubleCheckLockingTest.java | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/singleton/pom.xml b/singleton/pom.xml index e3d8f06e2ea5..038d6fdac040 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -38,5 +38,9 @@ junit-jupiter-engine test + + junit + junit + diff --git a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java index a7557fda37e0..6c17f7c3f001 100644 --- a/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java +++ b/singleton/src/main/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLocking.java @@ -35,12 +35,16 @@ public final class ThreadSafeDoubleCheckLocking { private static volatile ThreadSafeDoubleCheckLocking instance; + private static boolean flag = true; + /** * private constructor to prevent client from instantiating. */ private ThreadSafeDoubleCheckLocking() { // to prevent instantiating by Reflection call - if (instance != null) { + if (flag) { + flag = false; + } else { throw new IllegalStateException("Already initialized."); } } diff --git a/singleton/src/test/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLockingTest.java b/singleton/src/test/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLockingTest.java index 1d00d9f8f624..6286b09fb2a4 100644 --- a/singleton/src/test/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLockingTest.java +++ b/singleton/src/test/java/com/iluwatar/singleton/ThreadSafeDoubleCheckLockingTest.java @@ -22,6 +22,11 @@ */ package com.iluwatar.singleton; +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + /** * Date: 12/29/15 - 19:26 PM * @@ -36,4 +41,15 @@ public ThreadSafeDoubleCheckLockingTest() { super(ThreadSafeDoubleCheckLocking::getInstance); } + /** + * Test creating new instance by refection + */ + @Test(expected = InvocationTargetException.class) + public void testCreatingNewInstanceByRefection() throws Exception { + ThreadSafeDoubleCheckLocking instance1 = ThreadSafeDoubleCheckLocking.getInstance(); + Constructor constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor(); + constructor.setAccessible(true); + ThreadSafeDoubleCheckLocking instance2 = (ThreadSafeDoubleCheckLocking) constructor.newInstance(null); + } + } \ No newline at end of file From 88fae070e64dd90c94ed6008a7e15cd549badc17 Mon Sep 17 00:00:00 2001 From: snehalatapandit Date: Sat, 7 Sep 2019 23:48:13 +0530 Subject: [PATCH 24/28] Fix broken links #915 (#921) --- half-sync-half-async/README.md | 4 ++-- intercepting-filter/README.md | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/half-sync-half-async/README.md b/half-sync-half-async/README.md index 8a091f8133a3..ef463edadc6f 100644 --- a/half-sync-half-async/README.md +++ b/half-sync-half-async/README.md @@ -27,11 +27,11 @@ Use Half-Sync/Half-Async pattern when ## Real world examples -* [BSD Unix networking subsystem](http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf) +* [BSD Unix networking subsystem](https://www.dre.vanderbilt.edu/~schmidt/PDF/PLoP-95.pdf) * [Real Time CORBA](http://www.omg.org/news/meetings/workshops/presentations/realtime2001/4-3_Pyarali_thread-pool.pdf) * [Android AsyncTask framework](http://developer.android.com/reference/android/os/AsyncTask.html) ## Credits -* [Douglas C. Schmidt and Charles D. Cranor - Half Sync/Half Async](http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf) +* [Douglas C. Schmidt and Charles D. Cranor - Half Sync/Half Async](https://www.dre.vanderbilt.edu/~schmidt/PDF/PLoP-95.pdf) * [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) diff --git a/intercepting-filter/README.md b/intercepting-filter/README.md index 0d35044de8a7..c287138953eb 100644 --- a/intercepting-filter/README.md +++ b/intercepting-filter/README.md @@ -30,9 +30,8 @@ Use the Intercepting Filter pattern when ## Real world examples * [javax.servlet.FilterChain](https://tomcat.apache.org/tomcat-8.0-doc/servletapi/javax/servlet/FilterChain.html) and [javax.servlet.Filter](https://tomcat.apache.org/tomcat-8.0-doc/servletapi/javax/servlet/Filter.html) -* [Struts 2 - Interceptors](https://struts.apache.org/docs/interceptors.html) +* [Struts 2 - Interceptors](https://struts.apache.org/core-developers/interceptors.html) ## Credits * [TutorialsPoint - Intercepting Filter](http://www.tutorialspoint.com/design_pattern/intercepting_filter_pattern.htm) -* [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns) From 9bf7a059b8b716ea6fe4ae7b96ae2745877d2dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 8 Sep 2019 10:49:40 +0300 Subject: [PATCH 25/28] Java Design Patterns v1.21.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 +- 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 +- collection-pipeline/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-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-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 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/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 +- 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 +- 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 +- semaphore/pom.xml | 2 +- servant/pom.xml | 2 +- serverless/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/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 +- strategy/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 +- twin/pom.xml | 2 +- typeobjectpattern/pom.xml | 2 +- unit-of-work/pom.xml | 2 +- value-object/pom.xml | 2 +- visitor/pom.xml | 2 +- 128 files changed, 132 insertions(+), 132 deletions(-) diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml index bdcdd170a43a..452ac6319b15 100644 --- a/abstract-document/pom.xml +++ b/abstract-document/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 abstract-document diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index 00c9a491cf15..d0a6a4330466 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 abstract-factory diff --git a/acyclic-visitor/pom.xml b/acyclic-visitor/pom.xml index 4a0f740fdd42..9d091750ff5c 100644 --- a/acyclic-visitor/pom.xml +++ b/acyclic-visitor/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 acyclic-visitor diff --git a/adapter/pom.xml b/adapter/pom.xml index 0c47247dd8a7..5d0940b94261 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 adapter diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml index c4ad9cf1a4a9..5a23ad063480 100644 --- a/aggregator-microservices/aggregator-service/pom.xml +++ b/aggregator-microservices/aggregator-service/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml index 85992658990b..dd29d683057a 100644 --- a/aggregator-microservices/information-microservice/pom.xml +++ b/aggregator-microservices/information-microservice/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml index e19ba55533fb..66943eb8d701 100644 --- a/aggregator-microservices/inventory-microservice/pom.xml +++ b/aggregator-microservices/inventory-microservice/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/aggregator-microservices/pom.xml b/aggregator-microservices/pom.xml index 20e912395a05..98caca2070ff 100644 --- a/aggregator-microservices/pom.xml +++ b/aggregator-microservices/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 aggregator-microservices diff --git a/ambassador/pom.xml b/ambassador/pom.xml index efc8437051fe..ee04afc0af89 100644 --- a/ambassador/pom.xml +++ b/ambassador/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 ambassador diff --git a/api-gateway/api-gateway-service/pom.xml b/api-gateway/api-gateway-service/pom.xml index b17d71bfb905..bf96a660994a 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.21.0-SNAPSHOT + 1.21.0 4.0.0 api-gateway-service diff --git a/api-gateway/image-microservice/pom.xml b/api-gateway/image-microservice/pom.xml index bf70cda03c74..7ac0b9c90246 100644 --- a/api-gateway/image-microservice/pom.xml +++ b/api-gateway/image-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml index a46a511177a7..7d5adf478468 100644 --- a/api-gateway/pom.xml +++ b/api-gateway/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 api-gateway diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml index 33931cac5b2d..c3668a7f9558 100644 --- a/api-gateway/price-microservice/pom.xml +++ b/api-gateway/price-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 0c42bc970333..2bfbed289035 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 async-method-invocation diff --git a/balking/pom.xml b/balking/pom.xml index f20969b62765..a6e02fac8c29 100644 --- a/balking/pom.xml +++ b/balking/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/bridge/pom.xml b/bridge/pom.xml index cf45178a1925..a6082e24f3fa 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 bridge diff --git a/builder/pom.xml b/builder/pom.xml index dcf61fad5691..2f094dbfb33a 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 builder diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index ab2f1ae3cb2e..c1abe317e18d 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 business-delegate diff --git a/bytecode/pom.xml b/bytecode/pom.xml index e9e6247f8eb2..3e6fd5ca656c 100644 --- a/bytecode/pom.xml +++ b/bytecode/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/caching/pom.xml b/caching/pom.xml index c678aba4f4e4..b18d250b8ccd 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 caching diff --git a/callback/pom.xml b/callback/pom.xml index 46e9e2c9a5fe..04ab9c6fad5b 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 callback diff --git a/chain/pom.xml b/chain/pom.xml index 86b469ed828f..f992cf7871d0 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 chain diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml index 6003c9b4d7b3..3390f41dbf39 100644 --- a/collection-pipeline/pom.xml +++ b/collection-pipeline/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 collection-pipeline diff --git a/command/pom.xml b/command/pom.xml index 6d22f80a3ef1..c0eee39bffa7 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 command diff --git a/commander/pom.xml b/commander/pom.xml index bbf69b597113..baeee42fd564 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -3,7 +3,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 commander diff --git a/composite/pom.xml b/composite/pom.xml index 9d6f53e2cf08..4698ed1419b7 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 composite diff --git a/converter/pom.xml b/converter/pom.xml index 18b70a1d1e01..412d2509f741 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/cqrs/pom.xml b/cqrs/pom.xml index 428a9943a2f2..aeec001b0e28 100644 --- a/cqrs/pom.xml +++ b/cqrs/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 cqrs diff --git a/dao/pom.xml b/dao/pom.xml index addefc20873b..743bfc429641 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 dao diff --git a/data-bus/pom.xml b/data-bus/pom.xml index 918da99040d1..20d9f817bc6b 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -33,7 +33,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 data-bus diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml index e64f44747e55..ca48e87ad49f 100644 --- a/data-mapper/pom.xml +++ b/data-mapper/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 data-mapper diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index 79a54564430e..e7b0a5ddc734 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 data-transfer-object diff --git a/decorator/pom.xml b/decorator/pom.xml index e92b9dc492b2..f80026ff9209 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 decorator diff --git a/delegation/pom.xml b/delegation/pom.xml index 02b0fda4adeb..55fb8a14703e 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 21873c86813c..1dd72abcc33f 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 dependency-injection diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index de3ef48f0596..caaa58795935 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -29,11 +29,11 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 com.iluwatar dirty-flag - 1.21.0-SNAPSHOT + 1.21.0 dirty-flag http://maven.apache.org diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index 49ffe88a77fb..9d3ac69af8ac 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 double-checked-locking diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 22fe7a684bc3..11f66b11455b 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 double-dispatch diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml index 54de34334464..3f1e930c2f2c 100644 --- a/eip-aggregator/pom.xml +++ b/eip-aggregator/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml index fd7ee5c0e5e8..e0927ef5aa03 100644 --- a/eip-message-channel/pom.xml +++ b/eip-message-channel/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 eip-message-channel diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml index 2a041930d048..4d8711a563c3 100644 --- a/eip-publish-subscribe/pom.xml +++ b/eip-publish-subscribe/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 eip-publish-subscribe diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml index 3f5a79ca1dcc..d5aab1ed29f6 100644 --- a/eip-splitter/pom.xml +++ b/eip-splitter/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml index e3791102d367..a2b3aee8f556 100644 --- a/eip-wire-tap/pom.xml +++ b/eip-wire-tap/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index dca72de732eb..4ede7e366d80 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 event-aggregator diff --git a/event-asynchronous/pom.xml b/event-asynchronous/pom.xml index 908662d083d9..647296d0d629 100644 --- a/event-asynchronous/pom.xml +++ b/event-asynchronous/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 event-asynchronous diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index a336c9f13962..dc846f241173 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 event-driven-architecture diff --git a/event-queue/pom.xml b/event-queue/pom.xml index bd80ba5a4bec..2d341e7eb67b 100644 --- a/event-queue/pom.xml +++ b/event-queue/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 event-queue diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index 4b4d8c701cfa..8242cb502505 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 event-sourcing diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 6fd853ff571f..50b5672d4a81 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 execute-around diff --git a/extension-objects/pom.xml b/extension-objects/pom.xml index 2dee66d3aa46..340e59c44a9f 100644 --- a/extension-objects/pom.xml +++ b/extension-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/facade/pom.xml b/facade/pom.xml index 1b9bcb86ad4a..c608bfe4654f 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 facade diff --git a/factory-kit/pom.xml b/factory-kit/pom.xml index ac23757ec86d..9a4d9eae8b68 100644 --- a/factory-kit/pom.xml +++ b/factory-kit/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 factory-kit diff --git a/factory-method/pom.xml b/factory-method/pom.xml index 226c80958e1d..0a18f23a6c1e 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 factory-method diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index bd0fb5d71ce5..a9589047a86b 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 605537a73b8a..6276ee3836e1 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/flux/pom.xml b/flux/pom.xml index 726df234a27a..9f9c367196f2 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 flux diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 5bb8f2254950..0cd16209f4b4 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 flyweight diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 27dc990d110a..395fe55c4acf 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 front-controller diff --git a/guarded-suspension/pom.xml b/guarded-suspension/pom.xml index c944f8586951..3616ecfed7cd 100644 --- a/guarded-suspension/pom.xml +++ b/guarded-suspension/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 jar guarded-suspension diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index a532c619347e..f6f6b727a33f 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.21.0-SNAPSHOT + 1.21.0 half-sync-half-async diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml index a2c9f1925d51..d94f3ec4c3b3 100644 --- a/hexagonal/pom.xml +++ b/hexagonal/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 hexagonal diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index bf78e6792669..9b318c69cf27 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 intercepting-filter diff --git a/interpreter/pom.xml b/interpreter/pom.xml index 1274a4b69557..e0fb1df114ee 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 interpreter diff --git a/iterator/pom.xml b/iterator/pom.xml index fa06c9d3b0f0..88a626a9585e 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 iterator diff --git a/layers/pom.xml b/layers/pom.xml index cdd996ccb515..362109afb505 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 com.iluwatar.layers layers diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index 773dd7d8bed6..e2ccf22bee3b 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 lazy-loading diff --git a/marker/pom.xml b/marker/pom.xml index faa6868c237d..dabb13ece783 100644 --- a/marker/pom.xml +++ b/marker/pom.xml @@ -24,7 +24,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index 1c317bac9446..fdc0d4e91b6c 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 master-worker-pattern diff --git a/mediator/pom.xml b/mediator/pom.xml index d14e82bcc522..804f80ecee19 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 mediator diff --git a/memento/pom.xml b/memento/pom.xml index fc3e1954f76d..b48d66c4a080 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 memento diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index 523319a28e50..8bd3b5a5386d 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 model-view-controller diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index a4e91652820d..54616e2dbede 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 model-view-presenter model-view-presenter diff --git a/module/pom.xml b/module/pom.xml index 0320d97c0a8f..facf36cc813b 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 module diff --git a/monad/pom.xml b/monad/pom.xml index 45741ee1b6e7..ed29eebe20bd 100644 --- a/monad/pom.xml +++ b/monad/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 monad diff --git a/monostate/pom.xml b/monostate/pom.xml index d39071e261ea..09a43f5bf06f 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 monostate diff --git a/multiton/pom.xml b/multiton/pom.xml index beaccf3e3db8..8c3f1badbddc 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 multiton diff --git a/mute-idiom/pom.xml b/mute-idiom/pom.xml index 7cdbc5a42e0a..7d91bbe17a67 100644 --- a/mute-idiom/pom.xml +++ b/mute-idiom/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 mute-idiom diff --git a/mutex/pom.xml b/mutex/pom.xml index 85c5208d83b1..37188c21318b 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 mutex diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index 519e2cc0d883..c8029784e38e 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0-SNAPSHOT + 1.21.0 naked-objects-dom diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index cdb77b1b940e..c4d1f48bc4ee 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0-SNAPSHOT + 1.21.0 naked-objects-fixture diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index 460f2f5060cc..cfe74e43f01a 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0-SNAPSHOT + 1.21.0 naked-objects-integtests diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index 2a1832ea7e63..021374a6910d 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -15,7 +15,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 naked-objects @@ -350,17 +350,17 @@ ${project.groupId} naked-objects-dom - 1.21.0-SNAPSHOT + 1.21.0 ${project.groupId} naked-objects-fixture - 1.21.0-SNAPSHOT + 1.21.0 ${project.groupId} naked-objects-webapp - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index 54ccc40afae6..fff34db70edd 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0-SNAPSHOT + 1.21.0 naked-objects-webapp diff --git a/null-object/pom.xml b/null-object/pom.xml index 5c35e6a0a9e0..d5e1930c7ce2 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 null-object diff --git a/object-mother/pom.xml b/object-mother/pom.xml index c0ed50739c74..1e9b61af1d9d 100644 --- a/object-mother/pom.xml +++ b/object-mother/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 object-mother diff --git a/object-pool/pom.xml b/object-pool/pom.xml index fcb95db29fea..a3eb20c743ba 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 object-pool diff --git a/observer/pom.xml b/observer/pom.xml index 2248957c7179..0d1c18300798 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 observer diff --git a/page-object/pom.xml b/page-object/pom.xml index ae239725dbe7..169b9512e17d 100644 --- a/page-object/pom.xml +++ b/page-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 page-object pom diff --git a/page-object/sample-application/pom.xml b/page-object/sample-application/pom.xml index d78e46b28a78..e18312e15fb2 100644 --- a/page-object/sample-application/pom.xml +++ b/page-object/sample-application/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 sample-application diff --git a/page-object/test-automation/pom.xml b/page-object/test-automation/pom.xml index 7f8bcb12d0e9..dc5a17549b2c 100644 --- a/page-object/test-automation/pom.xml +++ b/page-object/test-automation/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 test-automation diff --git a/partial-response/pom.xml b/partial-response/pom.xml index 04b760ca833e..1bc6a1b6ccee 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index eb68f4a108e6..f701473b33ee 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 poison-pill diff --git a/pom.xml b/pom.xml index c55ed6492211..e4aeb5253457 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ 4.0.0 com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 pom 2014 diff --git a/priority-queue/pom.xml b/priority-queue/pom.xml index 9e5a788066c3..3fb50b5746de 100644 --- a/priority-queue/pom.xml +++ b/priority-queue/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index e01e81149459..fa2e4fc0d0a4 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 private-class-data diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index 4355df70256c..c09b8e47aa35 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 producer-consumer diff --git a/promise/pom.xml b/promise/pom.xml index 6c29939d5228..89ce50e997fc 100644 --- a/promise/pom.xml +++ b/promise/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 promise diff --git a/property/pom.xml b/property/pom.xml index dc0430fe3f97..68da0c2f52b2 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 property diff --git a/prototype/pom.xml b/prototype/pom.xml index ef81d38ecc2a..ab5fa9373af7 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 prototype diff --git a/proxy/pom.xml b/proxy/pom.xml index aef352a5d23a..98449c48f20f 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 proxy diff --git a/queue-load-leveling/pom.xml b/queue-load-leveling/pom.xml index 4b028e3565fe..0dcf4770e591 100644 --- a/queue-load-leveling/pom.xml +++ b/queue-load-leveling/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 queue-load-leveling diff --git a/reactor/pom.xml b/reactor/pom.xml index 6b561996d623..beebf7b83232 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 reactor diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index 460e58baa287..f7154a525012 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 reader-writer-lock diff --git a/repository/pom.xml b/repository/pom.xml index 36f73e344846..be05c82721ef 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 repository diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index 17985bdef53a..cd311e4e1a8f 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.21.0-SNAPSHOT + 1.21.0 resource-acquisition-is-initialization diff --git a/retry/pom.xml b/retry/pom.xml index 931873491ddd..d4d906e49d7b 100644 --- a/retry/pom.xml +++ b/retry/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 retry jar diff --git a/semaphore/pom.xml b/semaphore/pom.xml index bebd9b802c56..49363925f2a5 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 semaphore diff --git a/servant/pom.xml b/servant/pom.xml index e97b3a9895b2..60be0dd76903 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 servant diff --git a/serverless/pom.xml b/serverless/pom.xml index 89048283a472..92b525b65e5c 100644 --- a/serverless/pom.xml +++ b/serverless/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 diff --git a/service-layer/pom.xml b/service-layer/pom.xml index 2bd114c55ca2..942cc851980e 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 service-layer diff --git a/service-locator/pom.xml b/service-locator/pom.xml index fa6fcc4ba470..31f247ac5b26 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 service-locator diff --git a/singleton/pom.xml b/singleton/pom.xml index 038d6fdac040..a142faec0ebc 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 singleton diff --git a/spatial-partition/pom.xml b/spatial-partition/pom.xml index 22eb7a6f68fb..d0227f227b7d 100644 --- a/spatial-partition/pom.xml +++ b/spatial-partition/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 spatial-partition diff --git a/specification/pom.xml b/specification/pom.xml index 8723651051e2..26cce77656e0 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 specification diff --git a/state/pom.xml b/state/pom.xml index 9aeb4ec00cbd..a3499e5bf62e 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 state diff --git a/step-builder/pom.xml b/step-builder/pom.xml index ca5ed709d711..d11312def4bc 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 step-builder diff --git a/strategy/pom.xml b/strategy/pom.xml index a8dbbd007336..6d93322a1b54 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 strategy diff --git a/template-method/pom.xml b/template-method/pom.xml index 1345eaa6ca86..915e48f2f4a5 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 template-method diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index a77230bf2130..7d9263312817 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 thread-pool diff --git a/throttling/pom.xml b/throttling/pom.xml index d477af53f5aa..518b610e0de9 100644 --- a/throttling/pom.xml +++ b/throttling/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/tls/pom.xml b/tls/pom.xml index d3ccbfc2b79a..81c53be5dd02 100644 --- a/tls/pom.xml +++ b/tls/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 tls diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index 51554d7dce28..1ccd55ca4429 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 tolerant-reader diff --git a/trampoline/pom.xml b/trampoline/pom.xml index 338dc101604b..f7a95a54b128 100644 --- a/trampoline/pom.xml +++ b/trampoline/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 trampoline diff --git a/twin/pom.xml b/twin/pom.xml index 74e81ec0df44..fae948958aca 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 twin diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index 4e66263fefb7..a1546de05e2f 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 typeobjectpattern diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index b53075f21e8a..5fb8e9796838 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0-SNAPSHOT + 1.21.0 4.0.0 diff --git a/value-object/pom.xml b/value-object/pom.xml index 2b951d2a3135..3f31c8461e5d 100644 --- a/value-object/pom.xml +++ b/value-object/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 value-object diff --git a/visitor/pom.xml b/visitor/pom.xml index 618b547ea553..f159a28c0551 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0-SNAPSHOT + 1.21.0 visitor From b874adc29693de254ce47759f543ee4eec19c19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 8 Sep 2019 11:01:12 +0300 Subject: [PATCH 26/28] 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 +- 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 +- collection-pipeline/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-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-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 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/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 +- 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 +- 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 +- semaphore/pom.xml | 2 +- servant/pom.xml | 2 +- serverless/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/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 +- strategy/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 +- twin/pom.xml | 2 +- typeobjectpattern/pom.xml | 2 +- unit-of-work/pom.xml | 2 +- value-object/pom.xml | 2 +- visitor/pom.xml | 2 +- 128 files changed, 132 insertions(+), 132 deletions(-) diff --git a/abstract-document/pom.xml b/abstract-document/pom.xml index 452ac6319b15..c3f783184d33 100644 --- a/abstract-document/pom.xml +++ b/abstract-document/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT abstract-document diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index d0a6a4330466..402297ed9866 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT abstract-factory diff --git a/acyclic-visitor/pom.xml b/acyclic-visitor/pom.xml index 9d091750ff5c..a1f2bbf54f97 100644 --- a/acyclic-visitor/pom.xml +++ b/acyclic-visitor/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT acyclic-visitor diff --git a/adapter/pom.xml b/adapter/pom.xml index 5d0940b94261..c50050037fd7 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT adapter diff --git a/aggregator-microservices/aggregator-service/pom.xml b/aggregator-microservices/aggregator-service/pom.xml index 5a23ad063480..dbe303809f9b 100644 --- a/aggregator-microservices/aggregator-service/pom.xml +++ b/aggregator-microservices/aggregator-service/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/aggregator-microservices/information-microservice/pom.xml b/aggregator-microservices/information-microservice/pom.xml index dd29d683057a..b15af35e4b82 100644 --- a/aggregator-microservices/information-microservice/pom.xml +++ b/aggregator-microservices/information-microservice/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/aggregator-microservices/inventory-microservice/pom.xml b/aggregator-microservices/inventory-microservice/pom.xml index 66943eb8d701..1791ee72c9e8 100644 --- a/aggregator-microservices/inventory-microservice/pom.xml +++ b/aggregator-microservices/inventory-microservice/pom.xml @@ -29,7 +29,7 @@ aggregator-microservices com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/aggregator-microservices/pom.xml b/aggregator-microservices/pom.xml index 98caca2070ff..3bd1832499da 100644 --- a/aggregator-microservices/pom.xml +++ b/aggregator-microservices/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 aggregator-microservices diff --git a/ambassador/pom.xml b/ambassador/pom.xml index ee04afc0af89..2c2cf2c1c3c0 100644 --- a/ambassador/pom.xml +++ b/ambassador/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.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 bf96a660994a..82aa6aedef80 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.21.0 + 1.22.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 7ac0b9c90246..c4367cdd8f45 100644 --- a/api-gateway/image-microservice/pom.xml +++ b/api-gateway/image-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/api-gateway/pom.xml b/api-gateway/pom.xml index 7d5adf478468..69437e7c72ac 100644 --- a/api-gateway/pom.xml +++ b/api-gateway/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 api-gateway diff --git a/api-gateway/price-microservice/pom.xml b/api-gateway/price-microservice/pom.xml index c3668a7f9558..89aaba7ae7d4 100644 --- a/api-gateway/price-microservice/pom.xml +++ b/api-gateway/price-microservice/pom.xml @@ -29,7 +29,7 @@ api-gateway com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 2bfbed289035..c6764f61cad0 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT async-method-invocation diff --git a/balking/pom.xml b/balking/pom.xml index a6e02fac8c29..5da1ea43c71f 100644 --- a/balking/pom.xml +++ b/balking/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/bridge/pom.xml b/bridge/pom.xml index a6082e24f3fa..2480b06cffad 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT bridge diff --git a/builder/pom.xml b/builder/pom.xml index 2f094dbfb33a..0ae5bf1e8368 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT builder diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index c1abe317e18d..efe9e714586e 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT business-delegate diff --git a/bytecode/pom.xml b/bytecode/pom.xml index 3e6fd5ca656c..75b5a8c139aa 100644 --- a/bytecode/pom.xml +++ b/bytecode/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/caching/pom.xml b/caching/pom.xml index b18d250b8ccd..76578b8830cc 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT caching diff --git a/callback/pom.xml b/callback/pom.xml index 04ab9c6fad5b..8b74bcc9e8f9 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT callback diff --git a/chain/pom.xml b/chain/pom.xml index f992cf7871d0..443e8aee42b2 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT chain diff --git a/collection-pipeline/pom.xml b/collection-pipeline/pom.xml index 3390f41dbf39..9af2bd42ea73 100644 --- a/collection-pipeline/pom.xml +++ b/collection-pipeline/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT collection-pipeline diff --git a/command/pom.xml b/command/pom.xml index c0eee39bffa7..dc4f5edb92a0 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT command diff --git a/commander/pom.xml b/commander/pom.xml index baeee42fd564..68ff374203b7 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -3,7 +3,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT commander diff --git a/composite/pom.xml b/composite/pom.xml index 4698ed1419b7..327e497d757b 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT composite diff --git a/converter/pom.xml b/converter/pom.xml index 412d2509f741..ac1b88032fde 100644 --- a/converter/pom.xml +++ b/converter/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/cqrs/pom.xml b/cqrs/pom.xml index aeec001b0e28..beb195473ced 100644 --- a/cqrs/pom.xml +++ b/cqrs/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT cqrs diff --git a/dao/pom.xml b/dao/pom.xml index 743bfc429641..911ac6b05d1f 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT dao diff --git a/data-bus/pom.xml b/data-bus/pom.xml index 20d9f817bc6b..e5a2946951aa 100644 --- a/data-bus/pom.xml +++ b/data-bus/pom.xml @@ -33,7 +33,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT data-bus diff --git a/data-mapper/pom.xml b/data-mapper/pom.xml index ca48e87ad49f..baf8add13888 100644 --- a/data-mapper/pom.xml +++ b/data-mapper/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT data-mapper diff --git a/data-transfer-object/pom.xml b/data-transfer-object/pom.xml index e7b0a5ddc734..294f7cbbeebb 100644 --- a/data-transfer-object/pom.xml +++ b/data-transfer-object/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT data-transfer-object diff --git a/decorator/pom.xml b/decorator/pom.xml index f80026ff9209..71c64b331f99 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT decorator diff --git a/delegation/pom.xml b/delegation/pom.xml index 55fb8a14703e..89b0b7b4459e 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 1dd72abcc33f..2347cb14f946 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT dependency-injection diff --git a/dirty-flag/pom.xml b/dirty-flag/pom.xml index caaa58795935..31f7edd71284 100644 --- a/dirty-flag/pom.xml +++ b/dirty-flag/pom.xml @@ -29,11 +29,11 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT com.iluwatar dirty-flag - 1.21.0 + 1.22.0-SNAPSHOT dirty-flag http://maven.apache.org diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index 9d3ac69af8ac..4db5d6fe63bd 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT double-checked-locking diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 11f66b11455b..6b6c9064c939 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT double-dispatch diff --git a/eip-aggregator/pom.xml b/eip-aggregator/pom.xml index 3f1e930c2f2c..f56ae78deb73 100644 --- a/eip-aggregator/pom.xml +++ b/eip-aggregator/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/eip-message-channel/pom.xml b/eip-message-channel/pom.xml index e0927ef5aa03..9d91b7ead49d 100644 --- a/eip-message-channel/pom.xml +++ b/eip-message-channel/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT eip-message-channel diff --git a/eip-publish-subscribe/pom.xml b/eip-publish-subscribe/pom.xml index 4d8711a563c3..50c29e300162 100644 --- a/eip-publish-subscribe/pom.xml +++ b/eip-publish-subscribe/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT eip-publish-subscribe diff --git a/eip-splitter/pom.xml b/eip-splitter/pom.xml index d5aab1ed29f6..2bc3eec8402b 100644 --- a/eip-splitter/pom.xml +++ b/eip-splitter/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/eip-wire-tap/pom.xml b/eip-wire-tap/pom.xml index a2b3aee8f556..efca8d3c4cfb 100644 --- a/eip-wire-tap/pom.xml +++ b/eip-wire-tap/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index 4ede7e366d80..2e9f4d9a97fb 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT event-aggregator diff --git a/event-asynchronous/pom.xml b/event-asynchronous/pom.xml index 647296d0d629..5efa0252fba9 100644 --- a/event-asynchronous/pom.xml +++ b/event-asynchronous/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT event-asynchronous diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index dc846f241173..778949862727 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT event-driven-architecture diff --git a/event-queue/pom.xml b/event-queue/pom.xml index 2d341e7eb67b..dd08a6ae7337 100644 --- a/event-queue/pom.xml +++ b/event-queue/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT event-queue diff --git a/event-sourcing/pom.xml b/event-sourcing/pom.xml index 8242cb502505..c97921a1c731 100644 --- a/event-sourcing/pom.xml +++ b/event-sourcing/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT event-sourcing diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 50b5672d4a81..ac56665fd9f5 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT execute-around diff --git a/extension-objects/pom.xml b/extension-objects/pom.xml index 340e59c44a9f..37322cc011db 100644 --- a/extension-objects/pom.xml +++ b/extension-objects/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/facade/pom.xml b/facade/pom.xml index c608bfe4654f..4a8b3e412c7b 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT facade diff --git a/factory-kit/pom.xml b/factory-kit/pom.xml index 9a4d9eae8b68..54554a35447a 100644 --- a/factory-kit/pom.xml +++ b/factory-kit/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT factory-kit diff --git a/factory-method/pom.xml b/factory-method/pom.xml index 0a18f23a6c1e..cc4d21d1a4c8 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT factory-method diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index a9589047a86b..75da6ec9c0f9 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 6276ee3836e1..23fc5d806866 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/flux/pom.xml b/flux/pom.xml index 9f9c367196f2..424aaffd2bc2 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT flux diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 0cd16209f4b4..43b9d3ade3e6 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT flyweight diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 395fe55c4acf..d7c2da36ea51 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT front-controller diff --git a/guarded-suspension/pom.xml b/guarded-suspension/pom.xml index 3616ecfed7cd..e802eb4bd94a 100644 --- a/guarded-suspension/pom.xml +++ b/guarded-suspension/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT jar guarded-suspension diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index f6f6b727a33f..d965298ca364 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.21.0 + 1.22.0-SNAPSHOT half-sync-half-async diff --git a/hexagonal/pom.xml b/hexagonal/pom.xml index d94f3ec4c3b3..4f56a1020116 100644 --- a/hexagonal/pom.xml +++ b/hexagonal/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT hexagonal diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index 9b318c69cf27..c4183c7d0742 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT intercepting-filter diff --git a/interpreter/pom.xml b/interpreter/pom.xml index e0fb1df114ee..aa834b2edbb5 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT interpreter diff --git a/iterator/pom.xml b/iterator/pom.xml index 88a626a9585e..6eafcb92cb48 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT iterator diff --git a/layers/pom.xml b/layers/pom.xml index 362109afb505..8237c8f4f6e0 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT com.iluwatar.layers layers diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index e2ccf22bee3b..d5dacc7ce041 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT lazy-loading diff --git a/marker/pom.xml b/marker/pom.xml index dabb13ece783..afa82f4db4bf 100644 --- a/marker/pom.xml +++ b/marker/pom.xml @@ -24,7 +24,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/master-worker-pattern/pom.xml b/master-worker-pattern/pom.xml index fdc0d4e91b6c..be512fdef041 100644 --- a/master-worker-pattern/pom.xml +++ b/master-worker-pattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT master-worker-pattern diff --git a/mediator/pom.xml b/mediator/pom.xml index 804f80ecee19..14aadac8dd9b 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT mediator diff --git a/memento/pom.xml b/memento/pom.xml index b48d66c4a080..7eadc5839483 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT memento diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index 8bd3b5a5386d..64cb39f47f6e 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT model-view-controller diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index 54616e2dbede..2be7b30ca848 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT model-view-presenter model-view-presenter diff --git a/module/pom.xml b/module/pom.xml index facf36cc813b..df8c1494214d 100644 --- a/module/pom.xml +++ b/module/pom.xml @@ -28,7 +28,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT module diff --git a/monad/pom.xml b/monad/pom.xml index ed29eebe20bd..d9a436a6b569 100644 --- a/monad/pom.xml +++ b/monad/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT monad diff --git a/monostate/pom.xml b/monostate/pom.xml index 09a43f5bf06f..018e352483a4 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT monostate diff --git a/multiton/pom.xml b/multiton/pom.xml index 8c3f1badbddc..df26fe204470 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT multiton diff --git a/mute-idiom/pom.xml b/mute-idiom/pom.xml index 7d91bbe17a67..271e5265836c 100644 --- a/mute-idiom/pom.xml +++ b/mute-idiom/pom.xml @@ -21,7 +21,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT mute-idiom diff --git a/mutex/pom.xml b/mutex/pom.xml index 37188c21318b..2075fb4a2462 100644 --- a/mutex/pom.xml +++ b/mutex/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT mutex diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index c8029784e38e..69365bd4b00a 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0 + 1.22.0-SNAPSHOT naked-objects-dom diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index c4d1f48bc4ee..6426eb1d6473 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0 + 1.22.0-SNAPSHOT naked-objects-fixture diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index cfe74e43f01a..c4dd52dcf652 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0 + 1.22.0-SNAPSHOT naked-objects-integtests diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index 021374a6910d..8c21504bb6f5 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -15,7 +15,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT naked-objects @@ -350,17 +350,17 @@ ${project.groupId} naked-objects-dom - 1.21.0 + 1.22.0-SNAPSHOT ${project.groupId} naked-objects-fixture - 1.21.0 + 1.22.0-SNAPSHOT ${project.groupId} naked-objects-webapp - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index fff34db70edd..e3b8d122aba0 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -16,7 +16,7 @@ com.iluwatar naked-objects - 1.21.0 + 1.22.0-SNAPSHOT naked-objects-webapp diff --git a/null-object/pom.xml b/null-object/pom.xml index d5e1930c7ce2..f477b861c6d7 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT null-object diff --git a/object-mother/pom.xml b/object-mother/pom.xml index 1e9b61af1d9d..431d4d3b9dfb 100644 --- a/object-mother/pom.xml +++ b/object-mother/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT object-mother diff --git a/object-pool/pom.xml b/object-pool/pom.xml index a3eb20c743ba..a9a0fd044db1 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT object-pool diff --git a/observer/pom.xml b/observer/pom.xml index 0d1c18300798..dbe40f22f8ad 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT observer diff --git a/page-object/pom.xml b/page-object/pom.xml index 169b9512e17d..93bf25fc9a2e 100644 --- a/page-object/pom.xml +++ b/page-object/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT page-object pom diff --git a/page-object/sample-application/pom.xml b/page-object/sample-application/pom.xml index e18312e15fb2..44bc18a8c6b5 100644 --- a/page-object/sample-application/pom.xml +++ b/page-object/sample-application/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT sample-application diff --git a/page-object/test-automation/pom.xml b/page-object/test-automation/pom.xml index dc5a17549b2c..f657a8dab0b6 100644 --- a/page-object/test-automation/pom.xml +++ b/page-object/test-automation/pom.xml @@ -29,7 +29,7 @@ page-object com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT test-automation diff --git a/partial-response/pom.xml b/partial-response/pom.xml index 1bc6a1b6ccee..db70ffd1c883 100644 --- a/partial-response/pom.xml +++ b/partial-response/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index f701473b33ee..16ee086c7088 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT poison-pill diff --git a/pom.xml b/pom.xml index e4aeb5253457..cb5dbbd1c343 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ 4.0.0 com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT pom 2014 diff --git a/priority-queue/pom.xml b/priority-queue/pom.xml index 3fb50b5746de..aaf172ef3953 100644 --- a/priority-queue/pom.xml +++ b/priority-queue/pom.xml @@ -31,7 +31,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index fa2e4fc0d0a4..d3ea624a46b5 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT private-class-data diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index c09b8e47aa35..20cc0a1929e4 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT producer-consumer diff --git a/promise/pom.xml b/promise/pom.xml index 89ce50e997fc..8e7e92ddfccb 100644 --- a/promise/pom.xml +++ b/promise/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT promise diff --git a/property/pom.xml b/property/pom.xml index 68da0c2f52b2..d17aff7056ee 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT property diff --git a/prototype/pom.xml b/prototype/pom.xml index ab5fa9373af7..12416f41d54f 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT prototype diff --git a/proxy/pom.xml b/proxy/pom.xml index 98449c48f20f..e6b3ec76f7c4 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT proxy diff --git a/queue-load-leveling/pom.xml b/queue-load-leveling/pom.xml index 0dcf4770e591..bba4c44df34d 100644 --- a/queue-load-leveling/pom.xml +++ b/queue-load-leveling/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT queue-load-leveling diff --git a/reactor/pom.xml b/reactor/pom.xml index beebf7b83232..ff28b19ad090 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT reactor diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index f7154a525012..4a69cdb0c196 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT reader-writer-lock diff --git a/repository/pom.xml b/repository/pom.xml index be05c82721ef..48bca0cf2ba8 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT repository diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index cd311e4e1a8f..fc91d5c04c26 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.21.0 + 1.22.0-SNAPSHOT resource-acquisition-is-initialization diff --git a/retry/pom.xml b/retry/pom.xml index d4d906e49d7b..5d054183f1c7 100644 --- a/retry/pom.xml +++ b/retry/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT retry jar diff --git a/semaphore/pom.xml b/semaphore/pom.xml index 49363925f2a5..3761e5e49a8f 100644 --- a/semaphore/pom.xml +++ b/semaphore/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT semaphore diff --git a/servant/pom.xml b/servant/pom.xml index 60be0dd76903..1ee17aa9c919 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT servant diff --git a/serverless/pom.xml b/serverless/pom.xml index 92b525b65e5c..6156b41afd0e 100644 --- a/serverless/pom.xml +++ b/serverless/pom.xml @@ -26,7 +26,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT diff --git a/service-layer/pom.xml b/service-layer/pom.xml index 942cc851980e..403a896a4613 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT service-layer diff --git a/service-locator/pom.xml b/service-locator/pom.xml index 31f247ac5b26..948997f7aa8d 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT service-locator diff --git a/singleton/pom.xml b/singleton/pom.xml index a142faec0ebc..e518665d3ad8 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT singleton diff --git a/spatial-partition/pom.xml b/spatial-partition/pom.xml index d0227f227b7d..0ad20721166a 100644 --- a/spatial-partition/pom.xml +++ b/spatial-partition/pom.xml @@ -46,7 +46,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT spatial-partition diff --git a/specification/pom.xml b/specification/pom.xml index 26cce77656e0..38adf9b6fc8b 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT specification diff --git a/state/pom.xml b/state/pom.xml index a3499e5bf62e..f90da878680a 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT state diff --git a/step-builder/pom.xml b/step-builder/pom.xml index d11312def4bc..6021ecb2af39 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT step-builder diff --git a/strategy/pom.xml b/strategy/pom.xml index 6d93322a1b54..c421436f5f81 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT strategy diff --git a/template-method/pom.xml b/template-method/pom.xml index 915e48f2f4a5..e1f24ae251db 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT template-method diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index 7d9263312817..f05f6c2190e7 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT thread-pool diff --git a/throttling/pom.xml b/throttling/pom.xml index 518b610e0de9..e21d8b3c1232 100644 --- a/throttling/pom.xml +++ b/throttling/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/tls/pom.xml b/tls/pom.xml index 81c53be5dd02..596ebd37310d 100644 --- a/tls/pom.xml +++ b/tls/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT tls diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index 1ccd55ca4429..abf786059fa2 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT tolerant-reader diff --git a/trampoline/pom.xml b/trampoline/pom.xml index f7a95a54b128..e6f2e620afac 100644 --- a/trampoline/pom.xml +++ b/trampoline/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT trampoline diff --git a/twin/pom.xml b/twin/pom.xml index fae948958aca..15b4f6c1159f 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT twin diff --git a/typeobjectpattern/pom.xml b/typeobjectpattern/pom.xml index a1546de05e2f..f07460f49c54 100644 --- a/typeobjectpattern/pom.xml +++ b/typeobjectpattern/pom.xml @@ -27,7 +27,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT typeobjectpattern diff --git a/unit-of-work/pom.xml b/unit-of-work/pom.xml index 5fb8e9796838..fc11432e2923 100644 --- a/unit-of-work/pom.xml +++ b/unit-of-work/pom.xml @@ -29,7 +29,7 @@ java-design-patterns com.iluwatar - 1.21.0 + 1.22.0-SNAPSHOT 4.0.0 diff --git a/value-object/pom.xml b/value-object/pom.xml index 3f31c8461e5d..669ea521e470 100644 --- a/value-object/pom.xml +++ b/value-object/pom.xml @@ -30,7 +30,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT value-object diff --git a/visitor/pom.xml b/visitor/pom.xml index f159a28c0551..5fbc84142675 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ com.iluwatar java-design-patterns - 1.21.0 + 1.22.0-SNAPSHOT visitor From 019abc9980b9855bf04086c44b68f3282119c6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 10 Sep 2019 20:26:18 +0300 Subject: [PATCH 27/28] Add license headers --- .sonarcloud.properties | 23 +++++++++++++++++++++++ commander/pom.xml | 24 ++++++++++++++++++++++++ commander/properties/log4j.properties | 23 +++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/.sonarcloud.properties b/.sonarcloud.properties index 7a93b07aa76d..1bd690065c42 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -1,3 +1,26 @@ +# +# The MIT License +# Copyright (c) 2014 Ilkka Seppälä +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + # Path to sources #sonar.sources=. #sonar.exclusions= diff --git a/commander/pom.xml b/commander/pom.xml index 68ff374203b7..9639c4c9820b 100644 --- a/commander/pom.xml +++ b/commander/pom.xml @@ -1,3 +1,27 @@ + 4.0.0 diff --git a/commander/properties/log4j.properties b/commander/properties/log4j.properties index d7a52f503e83..1aaf1a4af6c8 100644 --- a/commander/properties/log4j.properties +++ b/commander/properties/log4j.properties @@ -1,3 +1,26 @@ +# +# The MIT License +# Copyright (c) 2014 Ilkka Seppälä +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + #Define root logger options log4j.rootLogger=TRACE, file, console From 5f39f7fbf71fd2799bb48384fc79efc4aba8e1ea Mon Sep 17 00:00:00 2001 From: Hemant Bothra Date: Fri, 20 Sep 2019 10:38:43 +0530 Subject: [PATCH 28/28] Updating README.md file to update doc as suggested in issue#925 (#926) --- adapter/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/adapter/README.md b/adapter/README.md index e943baba52fd..03334bf18262 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -56,15 +56,14 @@ public class FishingBoat { And captain expects an implementation of `RowingBoat` interface to be able to move ```java -public class Captain implements RowingBoat { +public class Captain { private RowingBoat rowingBoat; - + // default constructor and setter for rowingBoat public Captain(RowingBoat rowingBoat) { this.rowingBoat = rowingBoat; } - @Override public void row() { rowingBoat.row(); }