Merge pull request #1 from eugenp/master
merge from master changes into fork
This commit is contained in:
		
						commit
						d65bac08f4
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -43,3 +43,4 @@ spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties | ||||
| spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties | ||||
| *.springBeans | ||||
| 
 | ||||
| 20171220-JMeter.csv | ||||
|  | ||||
| @ -0,0 +1,52 @@ | ||||
| package com.baeldung.algorithms.maze.solver; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class BFSMazeSolver { | ||||
|     private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; | ||||
| 
 | ||||
|     public List<Coordinate> solve(Maze maze) { | ||||
|         LinkedList<Coordinate> nextToVisit = new LinkedList<>(); | ||||
|         Coordinate start = maze.getEntry(); | ||||
|         nextToVisit.add(start); | ||||
| 
 | ||||
|         while (!nextToVisit.isEmpty()) { | ||||
|             Coordinate cur = nextToVisit.remove(); | ||||
| 
 | ||||
|             if (!maze.isValidLocation(cur.getX(), cur.getY()) || maze.isExplored(cur.getX(), cur.getY())) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (maze.isWall(cur.getX(), cur.getY())) { | ||||
|                 maze.setVisited(cur.getX(), cur.getY(), true); | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (maze.isExit(cur.getX(), cur.getY())) { | ||||
|                 return backtrackPath(cur); | ||||
|             } | ||||
| 
 | ||||
|             for (int[] direction : DIRECTIONS) { | ||||
|                 Coordinate coordinate = new Coordinate(cur.getX() + direction[0], cur.getY() + direction[1], cur); | ||||
|                 nextToVisit.add(coordinate); | ||||
|                 maze.setVisited(cur.getX(), cur.getY(), true); | ||||
|             } | ||||
|         } | ||||
|         return Collections.emptyList(); | ||||
|     } | ||||
| 
 | ||||
|     private List<Coordinate> backtrackPath(Coordinate cur) { | ||||
|         List<Coordinate> path = new ArrayList<>(); | ||||
|         Coordinate iter = cur; | ||||
| 
 | ||||
|         while (iter != null) { | ||||
|             path.add(iter); | ||||
|             iter = iter.parent; | ||||
|         } | ||||
| 
 | ||||
|         return path; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,31 @@ | ||||
| package com.baeldung.algorithms.maze.solver; | ||||
| 
 | ||||
| public class Coordinate { | ||||
|     int x; | ||||
|     int y; | ||||
|     Coordinate parent; | ||||
| 
 | ||||
|     public Coordinate(int x, int y) { | ||||
|         this.x = x; | ||||
|         this.y = y; | ||||
|         this.parent = null; | ||||
|     } | ||||
| 
 | ||||
|     public Coordinate(int x, int y, Coordinate parent) { | ||||
|         this.x = x; | ||||
|         this.y = y; | ||||
|         this.parent = parent; | ||||
|     } | ||||
| 
 | ||||
|     int getX() { | ||||
|         return x; | ||||
|     } | ||||
| 
 | ||||
|     int getY() { | ||||
|         return y; | ||||
|     } | ||||
| 
 | ||||
|     Coordinate getParent() { | ||||
|         return parent; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,48 @@ | ||||
| package com.baeldung.algorithms.maze.solver; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class DFSMazeSolver { | ||||
|     private static final int[][] DIRECTIONS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; | ||||
| 
 | ||||
|     public List<Coordinate> solve(Maze maze) { | ||||
|         List<Coordinate> path = new ArrayList<>(); | ||||
|         if (explore(maze, maze.getEntry() | ||||
|             .getX(), | ||||
|             maze.getEntry() | ||||
|                 .getY(), | ||||
|             path)) { | ||||
|             return path; | ||||
|         } | ||||
|         return Collections.emptyList(); | ||||
|     } | ||||
| 
 | ||||
|     private boolean explore(Maze maze, int row, int col, List<Coordinate> path) { | ||||
|         if (!maze.isValidLocation(row, col) || maze.isWall(row, col) || maze.isExplored(row, col)) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         path.add(new Coordinate(row, col)); | ||||
|         maze.setVisited(row, col, true); | ||||
| 
 | ||||
|         if (maze.isExit(row, col)) { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         for (int[] direction : DIRECTIONS) { | ||||
|             Coordinate coordinate = getNextCoordinate(row, col, direction[0], direction[1]); | ||||
|             if (explore(maze, coordinate.getX(), coordinate.getY(), path)) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         path.remove(path.size() - 1); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     private Coordinate getNextCoordinate(int row, int col, int i, int j) { | ||||
|         return new Coordinate(row + i, col + j); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,141 @@ | ||||
| package com.baeldung.algorithms.maze.solver; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.Scanner; | ||||
| 
 | ||||
| public class Maze { | ||||
|     private static final int ROAD = 0; | ||||
|     private static final int WALL = 1; | ||||
|     private static final int START = 2; | ||||
|     private static final int EXIT = 3; | ||||
|     private static final int PATH = 4; | ||||
| 
 | ||||
|     private int[][] maze; | ||||
|     private boolean[][] visited; | ||||
|     private Coordinate start; | ||||
|     private Coordinate end; | ||||
| 
 | ||||
|     public Maze(File maze) throws FileNotFoundException { | ||||
|         String fileText = ""; | ||||
|         try (Scanner input = new Scanner(maze)) { | ||||
|             while (input.hasNextLine()) { | ||||
|                 fileText += input.nextLine() + "\n"; | ||||
|             } | ||||
|         } | ||||
|         initializeMaze(fileText); | ||||
|     } | ||||
| 
 | ||||
|     private void initializeMaze(String text) { | ||||
|         if (text == null || (text = text.trim()).length() == 0) { | ||||
|             throw new IllegalArgumentException("empty lines data"); | ||||
|         } | ||||
| 
 | ||||
|         String[] lines = text.split("[\r]?\n"); | ||||
|         maze = new int[lines.length][lines[0].length()]; | ||||
|         visited = new boolean[lines.length][lines[0].length()]; | ||||
| 
 | ||||
|         for (int row = 0; row < getHeight(); row++) { | ||||
|             if (lines[row].length() != getWidth()) { | ||||
|                 throw new IllegalArgumentException("line " + (row + 1) + " wrong length (was " + lines[row].length() + " but should be " + getWidth() + ")"); | ||||
|             } | ||||
| 
 | ||||
|             for (int col = 0; col < getWidth(); col++) { | ||||
|                 if (lines[row].charAt(col) == '#') | ||||
|                     maze[row][col] = WALL; | ||||
|                 else if (lines[row].charAt(col) == 'S') { | ||||
|                     maze[row][col] = START; | ||||
|                     start = new Coordinate(row, col); | ||||
|                 } else if (lines[row].charAt(col) == 'E') { | ||||
|                     maze[row][col] = EXIT; | ||||
|                     end = new Coordinate(row, col); | ||||
|                 } else | ||||
|                     maze[row][col] = ROAD; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public int getHeight() { | ||||
|         return maze.length; | ||||
|     } | ||||
| 
 | ||||
|     public int getWidth() { | ||||
|         return maze[0].length; | ||||
|     } | ||||
| 
 | ||||
|     public Coordinate getEntry() { | ||||
|         return start; | ||||
|     } | ||||
| 
 | ||||
|     public Coordinate getExit() { | ||||
|         return end; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isExit(int x, int y) { | ||||
|         return x == end.getX() && y == end.getY(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isStart(int x, int y) { | ||||
|         return x == start.getX() && y == start.getY(); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isExplored(int row, int col) { | ||||
|         return visited[row][col]; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isWall(int row, int col) { | ||||
|         return maze[row][col] == WALL; | ||||
|     } | ||||
| 
 | ||||
|     public void setVisited(int row, int col, boolean value) { | ||||
|         visited[row][col] = value; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isValidLocation(int row, int col) { | ||||
|         if (row < 0 || row >= getHeight() || col < 0 || col >= getWidth()) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public void printPath(List<Coordinate> path) { | ||||
|         int[][] tempMaze = Arrays.stream(maze) | ||||
|             .map(int[]::clone) | ||||
|             .toArray(int[][]::new); | ||||
|         for (Coordinate coordinate : path) { | ||||
|             if (isStart(coordinate.getX(), coordinate.getY()) || isExit(coordinate.getX(), coordinate.getY())) { | ||||
|                 continue; | ||||
|             } | ||||
|             tempMaze[coordinate.getX()][coordinate.getY()] = PATH; | ||||
|         } | ||||
|         System.out.println(toString(tempMaze)); | ||||
|     } | ||||
| 
 | ||||
|     public String toString(int[][] maze) { | ||||
|         StringBuilder result = new StringBuilder(getWidth() * (getHeight() + 1)); | ||||
|         for (int row = 0; row < getHeight(); row++) { | ||||
|             for (int col = 0; col < getWidth(); col++) { | ||||
|                 if (maze[row][col] == ROAD) { | ||||
|                     result.append(' '); | ||||
|                 } else if (maze[row][col] == WALL) { | ||||
|                     result.append('#'); | ||||
|                 } else if (maze[row][col] == START) { | ||||
|                     result.append('S'); | ||||
|                 } else if (maze[row][col] == EXIT) { | ||||
|                     result.append('E'); | ||||
|                 } else { | ||||
|                     result.append('.'); | ||||
|                 } | ||||
|             } | ||||
|             result.append('\n'); | ||||
|         } | ||||
|         return result.toString(); | ||||
|     } | ||||
| 
 | ||||
|     public void reset() { | ||||
|         for (int i = 0; i < visited.length; i++) | ||||
|             Arrays.fill(visited[i], false); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.algorithms.maze.solver; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class MazeDriver { | ||||
|     public static void main(String[] args) throws Exception { | ||||
|         File maze1 = new File("src/main/resources/maze/maze1.txt"); | ||||
|         File maze2 = new File("src/main/resources/maze/maze2.txt"); | ||||
| 
 | ||||
|         execute(maze1); | ||||
|         execute(maze2); | ||||
|     } | ||||
| 
 | ||||
|     private static void execute(File file) throws Exception { | ||||
|         Maze maze = new Maze(file); | ||||
|         dfs(maze); | ||||
|         bfs(maze); | ||||
|     } | ||||
| 
 | ||||
|     private static void bfs(Maze maze) { | ||||
|         BFSMazeSolver bfs = new BFSMazeSolver(); | ||||
|         List<Coordinate> path = bfs.solve(maze); | ||||
|         maze.printPath(path); | ||||
|         maze.reset(); | ||||
|     } | ||||
| 
 | ||||
|     private static void dfs(Maze maze) { | ||||
|         DFSMazeSolver dfs = new DFSMazeSolver(); | ||||
|         List<Coordinate> path = dfs.solve(maze); | ||||
|         maze.printPath(path); | ||||
|         maze.reset(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,104 @@ | ||||
| package com.baeldung.algorithms.sudoku; | ||||
| 
 | ||||
| import java.util.stream.IntStream; | ||||
| 
 | ||||
| public class BacktrackingAlgorithm { | ||||
| 
 | ||||
|     private static final int BOARD_SIZE = 9; | ||||
|     private static final int SUBSECTION_SIZE = 3; | ||||
|     private static final int BOARD_START_INDEX = 0; | ||||
| 
 | ||||
|     private static final int NO_VALUE = 0; | ||||
|     private static final int MIN_VALUE = 1; | ||||
|     private static final int MAX_VALUE = 9; | ||||
| 
 | ||||
|     private static int[][] board = { | ||||
|       {8, 0, 0, 0, 0, 0, 0, 0, 0}, | ||||
|       {0, 0, 3, 6, 0, 0, 0, 0, 0}, | ||||
|       {0, 7, 0, 0, 9, 0, 2, 0, 0}, | ||||
|       {0, 5, 0, 0, 0, 7, 0, 0, 0}, | ||||
|       {0, 0, 0, 0, 4, 5, 7, 0, 0}, | ||||
|       {0, 0, 0, 1, 0, 0, 0, 3, 0}, | ||||
|       {0, 0, 1, 0, 0, 0, 0, 6, 8}, | ||||
|       {0, 0, 8, 5, 0, 0, 0, 1, 0}, | ||||
|       {0, 9, 0, 0, 0, 0, 4, 0, 0} | ||||
|     }; | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         BacktrackingAlgorithm solver = new BacktrackingAlgorithm(); | ||||
|         solver.solve(board); | ||||
|         solver.printBoard(); | ||||
|     } | ||||
| 
 | ||||
|     private void printBoard() { | ||||
|         for (int row = BOARD_START_INDEX; row < BOARD_SIZE; row++) { | ||||
|             for (int column = BOARD_START_INDEX; column < BOARD_SIZE; column++) { | ||||
|                 System.out.print(board[row][column] + " "); | ||||
|             } | ||||
|             System.out.println(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private boolean solve(int[][] board) { | ||||
|         for (int r = BOARD_START_INDEX; r < BOARD_SIZE; r++) { | ||||
|             for (int c = BOARD_START_INDEX; c < BOARD_SIZE; c++) { | ||||
|                 if (board[r][c] == NO_VALUE) { | ||||
|                     for (int k = MIN_VALUE; k <= MAX_VALUE; k++) { | ||||
|                         board[r][c] = k; | ||||
|                         if (isValid(board, r, c) && solve(board)) { | ||||
|                             return true; | ||||
|                         } | ||||
|                         board[r][c] = NO_VALUE; | ||||
|                     } | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private boolean isValid(int[][] board, int r, int c) { | ||||
|         return rowConstraint(board, r) && | ||||
|           columnConstraint(board, c) && | ||||
|           subsectionConstraint(board, r, c); | ||||
|     } | ||||
| 
 | ||||
|     private boolean subsectionConstraint(int[][] board, int r, int c) { | ||||
|         boolean[] constraint = new boolean[BOARD_SIZE]; | ||||
|         int subsectionRowStart = (r / SUBSECTION_SIZE) * SUBSECTION_SIZE; | ||||
|         int subsectionRowEnd = subsectionRowStart + SUBSECTION_SIZE; | ||||
| 
 | ||||
|         int subsectionColumnStart = (c / SUBSECTION_SIZE) * SUBSECTION_SIZE; | ||||
|         int subsectionColumnEnd = subsectionColumnStart + SUBSECTION_SIZE; | ||||
| 
 | ||||
|         for (int i = subsectionRowStart; i < subsectionRowEnd; i++) { | ||||
|             for (int j = subsectionColumnStart; j < subsectionColumnEnd; j++) { | ||||
|                 if (!checkConstraint(board, i, constraint, j)) return false; | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private boolean columnConstraint(int[][] board, int c) { | ||||
|         boolean[] constraint = new boolean[BOARD_SIZE]; | ||||
|         return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) | ||||
|           .allMatch(i -> checkConstraint(board, i, constraint, c)); | ||||
|     } | ||||
| 
 | ||||
|     private boolean rowConstraint(int[][] board, int r) { | ||||
|         boolean[] constraint = new boolean[BOARD_SIZE]; | ||||
|         return IntStream.range(BOARD_START_INDEX, BOARD_SIZE) | ||||
|           .allMatch(i -> checkConstraint(board, r, constraint, i)); | ||||
|     } | ||||
| 
 | ||||
|     private boolean checkConstraint(int[][] board, int r, boolean[] constraint, int c) { | ||||
|         if (board[r][c] != NO_VALUE) { | ||||
|             if (!constraint[board[r][c] - 1]) { | ||||
|                 constraint[board[r][c] - 1] = true; | ||||
|             } else { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,33 @@ | ||||
| package com.baeldung.algorithms.sudoku; | ||||
| 
 | ||||
| class ColumnNode extends DancingNode { | ||||
|     int size; | ||||
|     String name; | ||||
| 
 | ||||
|     ColumnNode(String n) { | ||||
|         super(); | ||||
|         size = 0; | ||||
|         name = n; | ||||
|         C = this; | ||||
|     } | ||||
| 
 | ||||
|     void cover() { | ||||
|         unlinkLR(); | ||||
|         for (DancingNode i = this.D; i != this; i = i.D) { | ||||
|             for (DancingNode j = i.R; j != i; j = j.R) { | ||||
|                 j.unlinkUD(); | ||||
|                 j.C.size--; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void uncover() { | ||||
|         for (DancingNode i = this.U; i != this; i = i.U) { | ||||
|             for (DancingNode j = i.L; j != i; j = j.L) { | ||||
|                 j.C.size++; | ||||
|                 j.relinkUD(); | ||||
|             } | ||||
|         } | ||||
|         relinkLR(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,133 @@ | ||||
| package com.baeldung.algorithms.sudoku; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class DancingLinks { | ||||
| 
 | ||||
|     private ColumnNode header; | ||||
|     private List<DancingNode> answer; | ||||
| 
 | ||||
|     private void search(int k) { | ||||
|         if (header.R == header) { | ||||
|             handleSolution(answer); | ||||
|         } else { | ||||
|             ColumnNode c = selectColumnNodeHeuristic(); | ||||
|             c.cover(); | ||||
| 
 | ||||
|             for (DancingNode r = c.D; r != c; r = r.D) { | ||||
|                 answer.add(r); | ||||
| 
 | ||||
|                 for (DancingNode j = r.R; j != r; j = j.R) { | ||||
|                     j.C.cover(); | ||||
|                 } | ||||
| 
 | ||||
|                 search(k + 1); | ||||
| 
 | ||||
|                 r = answer.remove(answer.size() - 1); | ||||
|                 c = r.C; | ||||
| 
 | ||||
|                 for (DancingNode j = r.L; j != r; j = j.L) { | ||||
|                     j.C.uncover(); | ||||
|                 } | ||||
|             } | ||||
|             c.uncover(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private ColumnNode selectColumnNodeHeuristic() { | ||||
|         int min = Integer.MAX_VALUE; | ||||
|         ColumnNode ret = null; | ||||
|         for (ColumnNode c = (ColumnNode) header.R; c != header; c = (ColumnNode) c.R) { | ||||
|             if (c.size < min) { | ||||
|                 min = c.size; | ||||
|                 ret = c; | ||||
|             } | ||||
|         } | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     private ColumnNode makeDLXBoard(boolean[][] grid) { | ||||
|         final int COLS = grid[0].length; | ||||
| 
 | ||||
|         ColumnNode headerNode = new ColumnNode("header"); | ||||
|         List<ColumnNode> columnNodes = new ArrayList<>(); | ||||
| 
 | ||||
|         for (int i = 0; i < COLS; i++) { | ||||
|             ColumnNode n = new ColumnNode(Integer.toString(i)); | ||||
|             columnNodes.add(n); | ||||
|             headerNode = (ColumnNode) headerNode.hookRight(n); | ||||
|         } | ||||
|         headerNode = headerNode.R.C; | ||||
| 
 | ||||
|         for (boolean[] aGrid : grid) { | ||||
|             DancingNode prev = null; | ||||
|             for (int j = 0; j < COLS; j++) { | ||||
|                 if (aGrid[j]) { | ||||
|                     ColumnNode col = columnNodes.get(j); | ||||
|                     DancingNode newNode = new DancingNode(col); | ||||
|                     if (prev == null) | ||||
|                         prev = newNode; | ||||
|                     col.U.hookDown(newNode); | ||||
|                     prev = prev.hookRight(newNode); | ||||
|                     col.size++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         headerNode.size = COLS; | ||||
| 
 | ||||
|         return headerNode; | ||||
|     } | ||||
| 
 | ||||
|     DancingLinks(boolean[][] cover) { | ||||
|         header = makeDLXBoard(cover); | ||||
|     } | ||||
| 
 | ||||
|     public void runSolver() { | ||||
|         answer = new LinkedList<>(); | ||||
|         search(0); | ||||
|     } | ||||
| 
 | ||||
|     private void handleSolution(List<DancingNode> answer) { | ||||
|         int[][] result = parseBoard(answer); | ||||
|         printSolution(result); | ||||
|     } | ||||
| 
 | ||||
|     private int size = 9; | ||||
| 
 | ||||
|     private int[][] parseBoard(List<DancingNode> answer) { | ||||
|         int[][] result = new int[size][size]; | ||||
|         for (DancingNode n : answer) { | ||||
|             DancingNode rcNode = n; | ||||
|             int min = Integer.parseInt(rcNode.C.name); | ||||
|             for (DancingNode tmp = n.R; tmp != n; tmp = tmp.R) { | ||||
|                 int val = Integer.parseInt(tmp.C.name); | ||||
|                 if (val < min) { | ||||
|                     min = val; | ||||
|                     rcNode = tmp; | ||||
|                 } | ||||
|             } | ||||
|             int ans1 = Integer.parseInt(rcNode.C.name); | ||||
|             int ans2 = Integer.parseInt(rcNode.R.C.name); | ||||
|             int r = ans1 / size; | ||||
|             int c = ans1 % size; | ||||
|             int num = (ans2 % size) + 1; | ||||
|             result[r][c] = num; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     private static void printSolution(int[][] result) { | ||||
|         int size = result.length; | ||||
|         for (int[] aResult : result) { | ||||
|             StringBuilder ret = new StringBuilder(); | ||||
|             for (int j = 0; j < size; j++) { | ||||
|                 ret.append(aResult[j]).append(" "); | ||||
|             } | ||||
|             System.out.println(ret); | ||||
|         } | ||||
|         System.out.println(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,121 @@ | ||||
| package com.baeldung.algorithms.sudoku; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| public class DancingLinksAlgorithm { | ||||
|     private static final int BOARD_SIZE = 9; | ||||
|     private static final int SUBSECTION_SIZE = 3; | ||||
|     private static final int NO_VALUE = 0; | ||||
|     private static final int CONSTRAINTS = 4; | ||||
|     private static final int MIN_VALUE = 1; | ||||
|     private static final int MAX_VALUE = 9; | ||||
|     private static final int COVER_START_INDEX = 1; | ||||
| 
 | ||||
|     private static int[][] board = { | ||||
|       {8, 0, 0, 0, 0, 0, 0, 0, 0}, | ||||
|       {0, 0, 3, 6, 0, 0, 0, 0, 0}, | ||||
|       {0, 7, 0, 0, 9, 0, 2, 0, 0}, | ||||
|       {0, 5, 0, 0, 0, 7, 0, 0, 0}, | ||||
|       {0, 0, 0, 0, 4, 5, 7, 0, 0}, | ||||
|       {0, 0, 0, 1, 0, 0, 0, 3, 0}, | ||||
|       {0, 0, 1, 0, 0, 0, 0, 6, 8}, | ||||
|       {0, 0, 8, 5, 0, 0, 0, 1, 0}, | ||||
|       {0, 9, 0, 0, 0, 0, 4, 0, 0} | ||||
|     }; | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         DancingLinksAlgorithm solver = new DancingLinksAlgorithm(); | ||||
|         solver.solve(board); | ||||
|     } | ||||
| 
 | ||||
|     private void solve(int[][] board) { | ||||
|         boolean[][] cover = initializeExactCoverBoard(board); | ||||
|         DancingLinks dlx = new DancingLinks(cover); | ||||
|         dlx.runSolver(); | ||||
|     } | ||||
| 
 | ||||
|     private int getIndex(int row, int col, int num) { | ||||
|         return (row - 1) * BOARD_SIZE * BOARD_SIZE + (col - 1) * BOARD_SIZE + (num - 1); | ||||
|     } | ||||
| 
 | ||||
|     private boolean[][] createExactCoverBoard() { | ||||
|         boolean[][] coverBoard = new boolean[BOARD_SIZE * BOARD_SIZE * MAX_VALUE][BOARD_SIZE * BOARD_SIZE * CONSTRAINTS]; | ||||
| 
 | ||||
|         int hBase = 0; | ||||
|         hBase = checkCellConstraint(coverBoard, hBase); | ||||
|         hBase = checkRowConstraint(coverBoard, hBase); | ||||
|         hBase = checkColumnConstraint(coverBoard, hBase); | ||||
|         checkSubsectionConstraint(coverBoard, hBase); | ||||
|          | ||||
|         return coverBoard; | ||||
|     } | ||||
| 
 | ||||
|     private int checkSubsectionConstraint(boolean[][] coverBoard, int hBase) { | ||||
|         for (int br = COVER_START_INDEX; br <= BOARD_SIZE; br += SUBSECTION_SIZE) { | ||||
|             for (int bc = COVER_START_INDEX; bc <= BOARD_SIZE; bc += SUBSECTION_SIZE) { | ||||
|                 for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { | ||||
|                     for (int rDelta = 0; rDelta < SUBSECTION_SIZE; rDelta++) { | ||||
|                         for (int cDelta = 0; cDelta < SUBSECTION_SIZE; cDelta++) { | ||||
|                             int index = getIndex(br + rDelta, bc + cDelta, n); | ||||
|                             coverBoard[index][hBase] = true; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return hBase; | ||||
|     } | ||||
| 
 | ||||
|     private int checkColumnConstraint(boolean[][] coverBoard, int hBase) { | ||||
|         for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++) { | ||||
|             for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { | ||||
|                 for (int r1 = COVER_START_INDEX; r1 <= BOARD_SIZE; r1++) { | ||||
|                     int index = getIndex(r1, c, n); | ||||
|                     coverBoard[index][hBase] = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return hBase; | ||||
|     } | ||||
| 
 | ||||
|     private int checkRowConstraint(boolean[][] coverBoard, int hBase) { | ||||
|         for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { | ||||
|             for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++, hBase++) { | ||||
|                 for (int c1 = COVER_START_INDEX; c1 <= BOARD_SIZE; c1++) { | ||||
|                     int index = getIndex(r, c1, n); | ||||
|                     coverBoard[index][hBase] = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return hBase; | ||||
|     } | ||||
| 
 | ||||
|     private int checkCellConstraint(boolean[][] coverBoard, int hBase) { | ||||
|         for (int r = COVER_START_INDEX; r <= BOARD_SIZE; r++) { | ||||
|             for (int c = COVER_START_INDEX; c <= BOARD_SIZE; c++, hBase++) { | ||||
|                 for (int n = COVER_START_INDEX; n <= BOARD_SIZE; n++) { | ||||
|                     int index = getIndex(r, c, n); | ||||
|                     coverBoard[index][hBase] = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return hBase; | ||||
|     } | ||||
| 
 | ||||
|     private boolean[][] initializeExactCoverBoard(int[][] board) { | ||||
|         boolean[][] coverBoard = createExactCoverBoard(); | ||||
|         for (int i = COVER_START_INDEX; i <= BOARD_SIZE; i++) { | ||||
|             for (int j = COVER_START_INDEX; j <= BOARD_SIZE; j++) { | ||||
|                 int n = board[i - 1][j - 1]; | ||||
|                 if (n != NO_VALUE) { | ||||
|                     for (int num = MIN_VALUE; num <= MAX_VALUE; num++) { | ||||
|                         if (num != n) { | ||||
|                             Arrays.fill(coverBoard[getIndex(i, j, num)], false); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return coverBoard; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,50 @@ | ||||
| package com.baeldung.algorithms.sudoku; | ||||
| 
 | ||||
| class DancingNode { | ||||
|     DancingNode L, R, U, D; | ||||
|     ColumnNode C; | ||||
| 
 | ||||
|     DancingNode hookDown(DancingNode n1) { | ||||
|         assert (this.C == n1.C); | ||||
|         n1.D = this.D; | ||||
|         n1.D.U = n1; | ||||
|         n1.U = this; | ||||
|         this.D = n1; | ||||
|         return n1; | ||||
|     } | ||||
| 
 | ||||
|     DancingNode hookRight(DancingNode n1) { | ||||
|         n1.R = this.R; | ||||
|         n1.R.L = n1; | ||||
|         n1.L = this; | ||||
|         this.R = n1; | ||||
|         return n1; | ||||
|     } | ||||
| 
 | ||||
|     void unlinkLR() { | ||||
|         this.L.R = this.R; | ||||
|         this.R.L = this.L; | ||||
|     } | ||||
| 
 | ||||
|     void relinkLR() { | ||||
|         this.L.R = this.R.L = this; | ||||
|     } | ||||
| 
 | ||||
|     void unlinkUD() { | ||||
|         this.U.D = this.D; | ||||
|         this.D.U = this.U; | ||||
|     } | ||||
| 
 | ||||
|     void relinkUD() { | ||||
|         this.U.D = this.D.U = this; | ||||
|     } | ||||
| 
 | ||||
|     DancingNode() { | ||||
|         L = R = U = D = this; | ||||
|     } | ||||
| 
 | ||||
|     DancingNode(ColumnNode c) { | ||||
|         this(); | ||||
|         C = c; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										12
									
								
								algorithms/src/main/resources/maze/maze1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								algorithms/src/main/resources/maze/maze1.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| S ######## | ||||
| #        # | ||||
| # ### ## # | ||||
| # #    # # | ||||
| # #  # # # | ||||
| # ## ##### | ||||
| # #      # | ||||
| # # #  # # | ||||
| ##### #### | ||||
| #   #    E | ||||
| # #    # # | ||||
| ########## | ||||
							
								
								
									
										22
									
								
								algorithms/src/main/resources/maze/maze2.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								algorithms/src/main/resources/maze/maze2.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| S ########################## | ||||
| # #      #                 # | ||||
| # # ####   ############### # | ||||
| # # #    # #               # | ||||
| # # #### # # ############### | ||||
| # # #    # # #             # | ||||
| # # # #### ### ########### # | ||||
| # # # #        #           # | ||||
| #       ################## # | ||||
| #########    # # #       # # | ||||
| # #       #### # ####### # # | ||||
| # # ### ###  # # #       # # | ||||
| #   #       ##   # ##### # # | ||||
| ##### #######  # #     # # # | ||||
| #     #       ## ## #### # # | ||||
| # ##### #######     #      # | ||||
| #       #       ############ | ||||
| ####### #########        # # | ||||
| #       #         ######## # | ||||
| # ####### ###### ##   #    E | ||||
| #         #         #   ## # | ||||
| ############################ | ||||
| @ -0,0 +1,218 @@ | ||||
| package com.baeldung.java9.httpclient; | ||||
| 
 | ||||
| import jdk.incubator.http.HttpClient; | ||||
| import jdk.incubator.http.HttpRequest; | ||||
| import jdk.incubator.http.HttpResponse; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.*; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.CompletableFuture; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.ExecutorService; | ||||
| import java.util.concurrent.Executors; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import static org.hamcrest.CoreMatchers.containsString; | ||||
| import static org.hamcrest.CoreMatchers.equalTo; | ||||
| import static org.hamcrest.collection.IsEmptyCollection.empty; | ||||
| import static org.hamcrest.core.IsNot.not; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adam. | ||||
|  */ | ||||
| public class HttpClientTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromString("Sample body")) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newBuilder() | ||||
|             .proxy(ProxySelector.getDefault()) | ||||
|             .build() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), containsString("Sample body")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldNotFollowRedirectWhenSetToDefaultNever() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("http://stackoverflow.com")) | ||||
|             .version(HttpClient.Version.HTTP_1_1) | ||||
|             .GET() | ||||
|             .build(); | ||||
|         HttpResponse<String> response = HttpClient.newBuilder() | ||||
|             .build() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_MOVED_PERM)); | ||||
|         assertThat(response.body(), containsString("https://stackoverflow.com/")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldFollowRedirectWhenSetToAlways() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("http://stackoverflow.com")) | ||||
|             .version(HttpClient.Version.HTTP_1_1) | ||||
|             .GET() | ||||
|             .build(); | ||||
|         HttpResponse<String> response = HttpClient.newBuilder() | ||||
|             .followRedirects(HttpClient.Redirect.ALWAYS) | ||||
|             .build() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.finalRequest() | ||||
|             .uri() | ||||
|             .toString(), equalTo("https://stackoverflow.com/")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnOKStatusForAuthenticatedAccess() throws URISyntaxException, IOException, InterruptedException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/basic-auth")) | ||||
|             .GET() | ||||
|             .build(); | ||||
|         HttpResponse<String> response = HttpClient.newBuilder() | ||||
|             .authenticator(new Authenticator() { | ||||
|                 @Override | ||||
|                 protected PasswordAuthentication getPasswordAuthentication() { | ||||
|                     return new PasswordAuthentication("postman", "password".toCharArray()); | ||||
|                 } | ||||
|             }) | ||||
|             .build() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldSendRequestAsync() throws URISyntaxException, InterruptedException, ExecutionException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromString("Sample body")) | ||||
|             .build(); | ||||
|         CompletableFuture<HttpResponse<String>> response = HttpClient.newBuilder() | ||||
|             .build() | ||||
|             .sendAsync(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.get() | ||||
|             .statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldUseJustTwoThreadWhenProcessingSendAsyncRequest() throws URISyntaxException, InterruptedException, ExecutionException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         ExecutorService executorService = Executors.newFixedThreadPool(2); | ||||
| 
 | ||||
|         CompletableFuture<HttpResponse<String>> response1 = HttpClient.newBuilder() | ||||
|             .executor(executorService) | ||||
|             .build() | ||||
|             .sendAsync(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         CompletableFuture<HttpResponse<String>> response2 = HttpClient.newBuilder() | ||||
|             .executor(executorService) | ||||
|             .build() | ||||
|             .sendAsync(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         CompletableFuture<HttpResponse<String>> response3 = HttpClient.newBuilder() | ||||
|             .executor(executorService) | ||||
|             .build() | ||||
|             .sendAsync(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         CompletableFuture.allOf(response1, response2, response3) | ||||
|             .join(); | ||||
| 
 | ||||
|         assertThat(response1.get() | ||||
|             .statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response2.get() | ||||
|             .statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response3.get() | ||||
|             .statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldNotStoreCookieWhenPolicyAcceptNone() throws URISyntaxException, IOException, InterruptedException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpClient httpClient = HttpClient.newBuilder() | ||||
|             .cookieManager(new CookieManager(null, CookiePolicy.ACCEPT_NONE)) | ||||
|             .build(); | ||||
| 
 | ||||
|         httpClient.send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(httpClient.cookieManager() | ||||
|             .get() | ||||
|             .getCookieStore() | ||||
|             .getCookies(), empty()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldStoreCookieWhenPolicyAcceptAll() throws URISyntaxException, IOException, InterruptedException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpClient httpClient = HttpClient.newBuilder() | ||||
|             .cookieManager(new CookieManager(null, CookiePolicy.ACCEPT_ALL)) | ||||
|             .build(); | ||||
| 
 | ||||
|         httpClient.send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(httpClient.cookieManager() | ||||
|             .get() | ||||
|             .getCookieStore() | ||||
|             .getCookies(), not(empty())); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldProcessMultipleRequestViaStream() throws URISyntaxException, ExecutionException, InterruptedException { | ||||
|         List<URI> targets = Arrays.asList(new URI("https://postman-echo.com/get?foo1=bar1"), new URI("https://postman-echo.com/get?foo2=bar2")); | ||||
| 
 | ||||
|         HttpClient client = HttpClient.newHttpClient(); | ||||
| 
 | ||||
|         List<CompletableFuture<String>> futures = targets.stream() | ||||
|             .map(target -> client.sendAsync(HttpRequest.newBuilder(target) | ||||
|                 .GET() | ||||
|                 .build(), HttpResponse.BodyHandler.asString()) | ||||
|                 .thenApply(response -> response.body())) | ||||
|             .collect(Collectors.toList()); | ||||
| 
 | ||||
|         CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) | ||||
|             .join(); | ||||
| 
 | ||||
|         if (futures.get(0) | ||||
|             .get() | ||||
|             .contains("foo1")) { | ||||
|             assertThat(futures.get(0) | ||||
|                 .get(), containsString("bar1")); | ||||
|             assertThat(futures.get(1) | ||||
|                 .get(), containsString("bar2")); | ||||
|         } else { | ||||
|             assertThat(futures.get(1) | ||||
|                 .get(), containsString("bar2")); | ||||
|             assertThat(futures.get(1) | ||||
|                 .get(), containsString("bar1")); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,171 @@ | ||||
| package com.baeldung.java9.httpclient; | ||||
| 
 | ||||
| import jdk.incubator.http.HttpClient; | ||||
| import jdk.incubator.http.HttpRequest; | ||||
| import jdk.incubator.http.HttpResponse; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.IOException; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| import java.nio.file.Paths; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.time.Duration; | ||||
| 
 | ||||
| import static java.time.temporal.ChronoUnit.SECONDS; | ||||
| import static org.hamcrest.CoreMatchers.containsString; | ||||
| import static org.hamcrest.CoreMatchers.equalTo; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adam. | ||||
|  */ | ||||
| public class HttpRequestTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldUseHttp2WhenWebsiteUsesHttp2() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://stackoverflow.com")) | ||||
|             .version(HttpClient.Version.HTTP_2) | ||||
|             .GET() | ||||
|             .build(); | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.version(), equalTo(HttpClient.Version.HTTP_2)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldFallbackToHttp1_1WhenWebsiteDoesNotUseHttp2() throws IOException, InterruptedException, URISyntaxException, NoSuchAlgorithmException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .version(HttpClient.Version.HTTP_2) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.version(), equalTo(HttpClient.Version.HTTP_1_1)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnStatusOKWhenSendGetRequestWithDummyHeaders() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .headers("key1", "value1", "key2", "value2") | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnStatusOKWhenSendGetRequestTimeoutSet() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .timeout(Duration.of(10, SECONDS)) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnNoContentWhenPostWithNoBody() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .POST(HttpRequest.noBody()) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnSampleDataContentWhenPostWithBodyText() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromString("Sample request body")) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), containsString("Sample request body")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnSampleDataContentWhenPostWithInputStream() throws IOException, InterruptedException, URISyntaxException { | ||||
|         byte[] sampleData = "Sample request body".getBytes(); | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromInputStream(() -> new ByteArrayInputStream(sampleData))) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), containsString("Sample request body")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnSampleDataContentWhenPostWithByteArrayProcessorStream() throws IOException, InterruptedException, URISyntaxException { | ||||
|         byte[] sampleData = "Sample request body".getBytes(); | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromByteArray(sampleData)) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), containsString("Sample request body")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnSampleDataContentWhenPostWithFileProcessorStream() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/post")) | ||||
|             .headers("Content-Type", "text/plain;charset=UTF-8") | ||||
|             .POST(HttpRequest.BodyProcessor.fromFile(Paths.get("src/test/resources/sample.txt"))) | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), containsString("Sample file content")); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,55 @@ | ||||
| package com.baeldung.java9.httpclient; | ||||
| 
 | ||||
| import jdk.incubator.http.HttpClient; | ||||
| import jdk.incubator.http.HttpRequest; | ||||
| import jdk.incubator.http.HttpResponse; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URI; | ||||
| import java.net.URISyntaxException; | ||||
| 
 | ||||
| import static org.hamcrest.CoreMatchers.equalTo; | ||||
| import static org.hamcrest.Matchers.isEmptyString; | ||||
| import static org.hamcrest.core.IsNot.not; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adam. | ||||
|  */ | ||||
| public class HttpResponseTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("https://postman-echo.com/get")) | ||||
|             .GET() | ||||
|             .build(); | ||||
| 
 | ||||
|         HttpResponse<String> response = HttpClient.newHttpClient() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_OK)); | ||||
|         assertThat(response.body(), not(isEmptyString())); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void shouldResponseURIDifferentThanRequestUIRWhenRedirect() throws IOException, InterruptedException, URISyntaxException { | ||||
|         HttpRequest request = HttpRequest.newBuilder() | ||||
|             .uri(new URI("http://stackoverflow.com")) | ||||
|             .version(HttpClient.Version.HTTP_1_1) | ||||
|             .GET() | ||||
|             .build(); | ||||
|         HttpResponse<String> response = HttpClient.newBuilder() | ||||
|             .followRedirects(HttpClient.Redirect.ALWAYS) | ||||
|             .build() | ||||
|             .send(request, HttpResponse.BodyHandler.asString()); | ||||
| 
 | ||||
|         assertThat(request.uri() | ||||
|             .toString(), equalTo("http://stackoverflow.com")); | ||||
|         assertThat(response.uri() | ||||
|             .toString(), equalTo("https://stackoverflow.com/")); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| package com.baeldung.concurrent.prioritytaskexecution; | ||||
| 
 | ||||
| public class Job implements Runnable { | ||||
|     private String jobName; | ||||
|     private JobPriority jobPriority; | ||||
|      | ||||
|     public Job(String jobName, JobPriority jobPriority) { | ||||
|         this.jobName = jobName; | ||||
|         this.jobPriority = jobPriority != null ? jobPriority : JobPriority.MEDIUM; | ||||
|     } | ||||
| 
 | ||||
|     public JobPriority getJobPriority() { | ||||
|         return jobPriority; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void run() { | ||||
|         try { | ||||
|             System.out.println("Job:" + jobName + " Priority:" + jobPriority); | ||||
|             Thread.sleep(1000); | ||||
|         } catch (InterruptedException ignored) { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,7 @@ | ||||
| package com.baeldung.concurrent.prioritytaskexecution; | ||||
| 
 | ||||
| public enum JobPriority { | ||||
|     HIGH, | ||||
|     MEDIUM, | ||||
|     LOW | ||||
| } | ||||
| @ -0,0 +1,56 @@ | ||||
| package com.baeldung.concurrent.prioritytaskexecution; | ||||
| 
 | ||||
| import java.util.Comparator; | ||||
| import java.util.concurrent.ExecutorService; | ||||
| import java.util.concurrent.Executors; | ||||
| import java.util.concurrent.PriorityBlockingQueue; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| public class PriorityJobScheduler { | ||||
| 
 | ||||
|     private ExecutorService priorityJobPoolExecutor; | ||||
|     private ExecutorService priorityJobScheduler; | ||||
|     private PriorityBlockingQueue<Runnable> priorityQueue; | ||||
| 
 | ||||
|     public PriorityJobScheduler(Integer poolSize, Integer queueSize) { | ||||
|         priorityJobPoolExecutor = Executors.newFixedThreadPool(poolSize); | ||||
|         Comparator<? super Job> jobComparator = Comparator.comparing(Job::getJobPriority); | ||||
|         priorityQueue = new PriorityBlockingQueue<Runnable>(queueSize,  | ||||
|           (Comparator<? super Runnable>) jobComparator); | ||||
| 
 | ||||
|         priorityJobScheduler = Executors.newSingleThreadExecutor(); | ||||
|         priorityJobScheduler.execute(()->{ | ||||
|             while (true) { | ||||
|                 try { | ||||
|                     priorityJobPoolExecutor.execute(priorityQueue.take()); | ||||
|                 } catch (InterruptedException e) { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public void scheduleJob(Job job) { | ||||
|         priorityQueue.add(job); | ||||
|     } | ||||
| 
 | ||||
|     public int getQueuedTaskCount() { | ||||
|         return priorityQueue.size(); | ||||
|     } | ||||
| 
 | ||||
|     protected void close(ExecutorService scheduler) { | ||||
|         scheduler.shutdown(); | ||||
|         try { | ||||
|             if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) { | ||||
|                 scheduler.shutdownNow(); | ||||
|             } | ||||
|         } catch (InterruptedException e) { | ||||
|             scheduler.shutdownNow(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void closeScheduler() { | ||||
|         close(priorityJobPoolExecutor); | ||||
|         close(priorityJobScheduler); | ||||
|     } | ||||
| } | ||||
| @ -1,7 +1,5 @@ | ||||
| package com.baeldung.concurrent.waitandnotify; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| 
 | ||||
| public class Data { | ||||
|     private String packet; | ||||
|      | ||||
| @ -14,6 +12,7 @@ public class Data { | ||||
|             try { | ||||
|                 wait(); | ||||
|             } catch (InterruptedException e) { | ||||
|                 Thread.currentThread().interrupt();  | ||||
|                 System.out.println("Thread Interrupted"); | ||||
|             } | ||||
|         } | ||||
| @ -28,6 +27,7 @@ public class Data { | ||||
|             try {  | ||||
|                 wait(); | ||||
|             } catch (InterruptedException e) { | ||||
|                 Thread.currentThread().interrupt();  | ||||
|                 System.out.println("Thread Interrupted"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -20,6 +20,7 @@ public class Receiver implements Runnable { | ||||
|             try { | ||||
|                 Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); | ||||
|             } catch (InterruptedException e) { | ||||
|                 Thread.currentThread().interrupt();  | ||||
|                 System.out.println("Thread Interrupted"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -25,6 +25,7 @@ public class Sender implements Runnable { | ||||
|             try { | ||||
|                 Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); | ||||
|             } catch (InterruptedException e) { | ||||
|                 Thread.currentThread().interrupt();  | ||||
|                 System.out.println("Thread Interrupted"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -0,0 +1,38 @@ | ||||
| package com.baeldung.concurrent.prioritytaskexecution; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class PriorityJobSchedulerUnitTest { | ||||
|     private static int POOL_SIZE = 1; | ||||
|     private static int QUEUE_SIZE = 10; | ||||
|      | ||||
|     @Test | ||||
|     public void whenMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked() { | ||||
|         Job job1 = new Job("Job1", JobPriority.LOW); | ||||
|         Job job2 = new Job("Job2", JobPriority.MEDIUM); | ||||
|         Job job3 = new Job("Job3", JobPriority.HIGH); | ||||
|         Job job4 = new Job("Job4", JobPriority.MEDIUM); | ||||
|         Job job5 = new Job("Job5", JobPriority.LOW); | ||||
|         Job job6 = new Job("Job6", JobPriority.HIGH); | ||||
|          | ||||
|         PriorityJobScheduler pjs = new PriorityJobScheduler(POOL_SIZE, QUEUE_SIZE); | ||||
|          | ||||
|         pjs.scheduleJob(job1); | ||||
|         pjs.scheduleJob(job2); | ||||
|         pjs.scheduleJob(job3); | ||||
|         pjs.scheduleJob(job4); | ||||
|         pjs.scheduleJob(job5); | ||||
|         pjs.scheduleJob(job6); | ||||
|          | ||||
|         // ensure no tasks is pending before closing the scheduler | ||||
|         while (pjs.getQueuedTaskCount() != 0); | ||||
|          | ||||
|         // delay to avoid job sleep (added for demo) being interrupted | ||||
|         try { | ||||
|             Thread.sleep(2000); | ||||
|         } catch (InterruptedException ignored) { | ||||
|         } | ||||
|          | ||||
|         pjs.closeScheduler(); | ||||
|     } | ||||
| } | ||||
| @ -57,7 +57,8 @@ public class NetworkIntegrationTest { | ||||
|             sender.join(); | ||||
|             receiver.join(); | ||||
|         } catch (InterruptedException e) { | ||||
|             e.printStackTrace(); | ||||
|             Thread.currentThread().interrupt();  | ||||
|             System.out.println("Thread Interrupted"); | ||||
|         } | ||||
|          | ||||
|         assertEquals(expected, outContent.toString()); | ||||
|  | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| public interface Channel { | ||||
|     public void update(Object o); | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class NewsAgency { | ||||
|     private String news; | ||||
|     private List<Channel> channels = new ArrayList<>(); | ||||
| 
 | ||||
|     public void addObserver(Channel channel) { | ||||
|         this.channels.add(channel); | ||||
|     } | ||||
| 
 | ||||
|     public void removeObserver(Channel channel) { | ||||
|         this.channels.remove(channel); | ||||
|     } | ||||
| 
 | ||||
|     public void setNews(String news) { | ||||
|         this.news = news; | ||||
|         for (Channel channel : this.channels) { | ||||
|             channel.update(this.news); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| public class NewsChannel implements Channel { | ||||
| 
 | ||||
|     private String news; | ||||
| 
 | ||||
|     @Override | ||||
|     public void update(Object news) { | ||||
|         this.setNews((String) news); | ||||
|     } | ||||
| 
 | ||||
|     public String getNews() { | ||||
|         return news; | ||||
|     } | ||||
| 
 | ||||
|     public void setNews(String news) { | ||||
|         this.news = news; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import java.util.Observable; | ||||
| 
 | ||||
| public class ONewsAgency extends Observable { | ||||
|     private String news; | ||||
| 
 | ||||
|     public void setNews(String news) { | ||||
|         this.news = news; | ||||
|         setChanged(); | ||||
|         notifyObservers(news); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import java.util.Observable; | ||||
| import java.util.Observer; | ||||
| 
 | ||||
| public class ONewsChannel implements Observer { | ||||
| 
 | ||||
|     private String news; | ||||
| 
 | ||||
|     @Override | ||||
|     public void update(Observable o, Object news) { | ||||
|         this.setNews((String) news); | ||||
|     } | ||||
| 
 | ||||
|     public String getNews() { | ||||
|         return news; | ||||
|     } | ||||
| 
 | ||||
|     public void setNews(String news) { | ||||
|         this.news = news; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,28 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import java.beans.PropertyChangeListener; | ||||
| import java.beans.PropertyChangeSupport; | ||||
| 
 | ||||
| public class PCLNewsAgency { | ||||
|     private String news; | ||||
| 
 | ||||
|     private PropertyChangeSupport support; | ||||
| 
 | ||||
|     public PCLNewsAgency() { | ||||
|         support = new PropertyChangeSupport(this); | ||||
|     } | ||||
| 
 | ||||
|     public void addPropertyChangeListener(PropertyChangeListener pcl) { | ||||
|         support.addPropertyChangeListener(pcl); | ||||
|     } | ||||
| 
 | ||||
|     public void removePropertyChangeListener(PropertyChangeListener pcl) { | ||||
|         support.removePropertyChangeListener(pcl); | ||||
|     } | ||||
| 
 | ||||
|     public void setNews(String value) { | ||||
|         support.firePropertyChange("news", this.news, value); | ||||
|         this.news = value; | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import java.beans.PropertyChangeEvent; | ||||
| import java.beans.PropertyChangeListener; | ||||
| 
 | ||||
| public class PCLNewsChannel implements PropertyChangeListener { | ||||
| 
 | ||||
|     private String news; | ||||
| 
 | ||||
|     public void propertyChange(PropertyChangeEvent evt) { | ||||
|         this.setNews((String) evt.getNewValue()); | ||||
|     } | ||||
| 
 | ||||
|     public String getNews() { | ||||
|         return news; | ||||
|     } | ||||
| 
 | ||||
|     public void setNews(String news) { | ||||
|         this.news = news; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										16
									
								
								core-java/src/main/java/com/baeldung/javac/Data.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								core-java/src/main/java/com/baeldung/javac/Data.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| package com.baeldung.javac; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class Data { | ||||
|     List<String> textList = new ArrayList(); | ||||
| 
 | ||||
|     public void addText(String text) { | ||||
|         textList.add(text); | ||||
|     } | ||||
| 
 | ||||
|     public List getTextList() { | ||||
|         return this.textList; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										53
									
								
								core-java/src/main/java/com/baeldung/string/Palindrome.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								core-java/src/main/java/com/baeldung/string/Palindrome.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.string; | ||||
| 
 | ||||
| public class Palindrome { | ||||
| 
 | ||||
|     public boolean isPalindrome(String text) { | ||||
|         text = text.replaceAll("\\s+", "") | ||||
|             .toLowerCase(); | ||||
|         int length = text.length(); | ||||
|         int forward = 0; | ||||
|         int backward = length - 1; | ||||
|         boolean palindrome = true; | ||||
|         while (backward > forward) { | ||||
|             char forwardChar = text.charAt(forward++); | ||||
|             char backwardChar = text.charAt(backward--); | ||||
|             if (forwardChar != backwardChar) | ||||
|                 return false; | ||||
|         } | ||||
|         return palindrome; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isPalindromeReverseTheString(String text) { | ||||
|         String reverse = ""; | ||||
|         text = text.replaceAll("\\s+", "").toLowerCase(); | ||||
|         char[] plain = text.toCharArray(); | ||||
|         for (int i = plain.length - 1; i >= 0; i--) | ||||
|             reverse += plain[i]; | ||||
|         return reverse.equals(text); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isPalindromeUsingStringBuilder(String text) { | ||||
|         StringBuilder plain = new StringBuilder(text); | ||||
|         StringBuilder reverse = plain.reverse(); | ||||
|         return reverse.equals(plain); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isPalindromeUsingStringBuffer(String text) { | ||||
|         StringBuffer plain = new StringBuffer(text); | ||||
|         StringBuffer reverse = plain.reverse(); | ||||
|         return reverse.equals(plain); | ||||
|     } | ||||
| 
 | ||||
|     public boolean isPalindromeRecursive(String text, int forward, int backward) { | ||||
|         if (forward == backward) | ||||
|             return true; | ||||
|         if ((text.charAt(forward)) != (text.charAt(backward))) | ||||
|             return false; | ||||
|         if (forward < backward + 1) { | ||||
|             return isPalindromeRecursive(text, forward + 1, backward - 1); | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2
									
								
								core-java/src/main/java/javac-args/arguments
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								core-java/src/main/java/javac-args/arguments
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| -d javac-target -verbose | ||||
| com/baeldung/javac/Data.java | ||||
							
								
								
									
										2
									
								
								core-java/src/main/java/javac-args/options
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								core-java/src/main/java/javac-args/options
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| -d javac-target | ||||
| -verbose | ||||
							
								
								
									
										1
									
								
								core-java/src/main/java/javac-args/types
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								core-java/src/main/java/javac-args/types
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| com/baeldung/javac/Data.java | ||||
							
								
								
									
										3
									
								
								core-java/src/main/java/javac-args/xlint-ops
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								core-java/src/main/java/javac-args/xlint-ops
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| -d javac-target | ||||
| -Xlint:rawtypes,unchecked,static,cast,serial,fallthrough | ||||
| com/baeldung/javac/Data.java | ||||
| @ -0,0 +1,47 @@ | ||||
| package com.baeldung.designpatterns.observer; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import com.baeldung.designpatterns.observer.NewsAgency; | ||||
| import com.baeldung.designpatterns.observer.NewsChannel; | ||||
| 
 | ||||
| public class ObserverIntegrationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenChangingNewsAgencyState_thenNewsChannelNotified() { | ||||
| 
 | ||||
|         NewsAgency observable = new NewsAgency(); | ||||
|         NewsChannel observer = new NewsChannel(); | ||||
| 
 | ||||
|         observable.addObserver(observer); | ||||
| 
 | ||||
|         observable.setNews("news"); | ||||
|         assertEquals(observer.getNews(), "news"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenChangingONewsAgencyState_thenONewsChannelNotified() { | ||||
| 
 | ||||
|         ONewsAgency observable = new ONewsAgency(); | ||||
|         ONewsChannel observer = new ONewsChannel(); | ||||
| 
 | ||||
|         observable.addObserver(observer); | ||||
| 
 | ||||
|         observable.setNews("news"); | ||||
|         assertEquals(observer.getNews(), "news"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenChangingPCLNewsAgencyState_thenONewsChannelNotified() { | ||||
| 
 | ||||
|         PCLNewsAgency observable = new PCLNewsAgency(); | ||||
|         PCLNewsChannel observer = new PCLNewsChannel(); | ||||
| 
 | ||||
|         observable.addPropertyChangeListener(observer); | ||||
| 
 | ||||
|         observable.setNews("news"); | ||||
|         assertEquals(observer.getNews(), "news"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,114 @@ | ||||
| package com.baeldung.string; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class WhenCheckingPalindrome { | ||||
| 
 | ||||
|     private String[] words = { | ||||
|             "Anna", | ||||
|             "Civic", | ||||
|             "Kayak", | ||||
|             "Level", | ||||
|             "Madam", | ||||
|     }; | ||||
| 
 | ||||
|     private String[] sentences = { | ||||
|             "Sore was I ere I saw Eros", | ||||
|             "Euston saw I was not Sue", | ||||
|             "Too hot to hoot", | ||||
|             "No mists or frost Simon", | ||||
|             "Stella won no wallets" | ||||
|     }; | ||||
|      | ||||
|     private Palindrome palindrome = new Palindrome(); | ||||
|      | ||||
|     @Test | ||||
|     public void whenWord_shouldBePalindrome() { | ||||
|         for(String word:words) | ||||
|             Assert.assertTrue(palindrome.isPalindrome(word)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenSentence_shouldBePalindrome() { | ||||
|         for(String sentence:sentences) | ||||
|             Assert.assertTrue(palindrome.isPalindrome(sentence)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenReverseWord_shouldBePalindrome() { | ||||
|         for(String word:words) | ||||
|             Assert.assertTrue(palindrome.isPalindromeReverseTheString(word)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenReverseSentence_shouldBePalindrome() { | ||||
|         for(String sentence:sentences) | ||||
|             Assert.assertTrue(palindrome.isPalindromeReverseTheString(sentence)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenStringBuilderWord_shouldBePalindrome() { | ||||
|         for(String word:words) | ||||
|             Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(word)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenStringBuilderSentence_shouldBePalindrome() { | ||||
|         for(String sentence:sentences) | ||||
|             Assert.assertTrue(palindrome.isPalindromeUsingStringBuilder(sentence)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenStringBufferWord_shouldBePalindrome() { | ||||
|         for(String word:words) | ||||
|             Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(word)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenStringBufferSentence_shouldBePalindrome() { | ||||
|         for(String sentence:sentences) | ||||
|              | ||||
|             Assert.assertTrue(palindrome.isPalindromeUsingStringBuffer(sentence)); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenPalindromeRecursive_wordShouldBePalindrome() { | ||||
|         for(String word:words) { | ||||
|             word = word.replaceAll("\\s+", "").toLowerCase(); | ||||
|             int backward = word.length()-1; | ||||
|              | ||||
|             Assert.assertTrue(palindrome.isPalindromeRecursive(word,0,backward)); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenPalindromeRecursive_sentenceShouldBePalindrome() { | ||||
|         for(String sentence:sentences) { | ||||
|             sentence = sentence.replaceAll("\\s+", "").toLowerCase(); | ||||
|             int backward = sentence.length()-1; | ||||
|              | ||||
|             Assert.assertTrue(palindrome.isPalindromeRecursive(sentence,0,backward)); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenPalindromeStreams_wordShouldBePalindrome() { | ||||
|         String[] expected = Arrays.stream(words) | ||||
|             .filter(palindrome::isPalindrome) | ||||
|             .toArray(String[]::new); | ||||
|          | ||||
|         Assert.assertArrayEquals(expected, words); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void whenPalindromeStreams_sentenceShouldBePalindrome() { | ||||
|         String[] expected = Arrays.stream(sentences) | ||||
|             .filter(palindrome::isPalindrome) | ||||
|             .toArray(String[]::new); | ||||
|          | ||||
|         Assert.assertArrayEquals(expected, sentences); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| package com.baeldung.kotlin | ||||
| 
 | ||||
| import org.junit.Assert | ||||
| import org.junit.Test | ||||
| 
 | ||||
| class InfixFunctionsTest { | ||||
|     @Test | ||||
|     fun testColours() { | ||||
|         val color = 0x123456 | ||||
|         val red = (color and 0xff0000) shr 16 | ||||
|         val green = (color and 0x00ff00) shr 8 | ||||
|         val blue = (color and 0x0000ff) shr 0 | ||||
| 
 | ||||
|         Assert.assertEquals(0x12, red) | ||||
|         Assert.assertEquals(0x34, green) | ||||
|         Assert.assertEquals(0x56, blue) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun testNewAssertions() { | ||||
|         class Assertion<T>(private val target: T) { | ||||
|             infix fun isEqualTo(other: T) { | ||||
|                 Assert.assertEquals(other, target) | ||||
|             } | ||||
| 
 | ||||
|             infix fun isDifferentFrom(other: T) { | ||||
|                 Assert.assertNotEquals(other, target) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         val result = Assertion(5) | ||||
| 
 | ||||
|         result isEqualTo 5 | ||||
| 
 | ||||
|         // The following two lines are expected to fail | ||||
|         // result isEqualTo 6 | ||||
|         // result isDifferentFrom 5 | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun testNewStringMethod() { | ||||
|         infix fun String.substringMatches(r: Regex) : List<String> { | ||||
|             return r.findAll(this) | ||||
|                     .map { it.value } | ||||
|                     .toList() | ||||
|         } | ||||
| 
 | ||||
|         val matches = "a bc def" substringMatches ".*? ".toRegex() | ||||
|         Assert.assertEquals(listOf("a ", "bc "), matches) | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,128 @@ | ||||
| package com.baeldung.kotlin.stdlib | ||||
| 
 | ||||
| import org.junit.Test | ||||
| import java.beans.ExceptionListener | ||||
| import java.beans.XMLEncoder | ||||
| import java.io.* | ||||
| import java.lang.Exception | ||||
| import kotlin.test.* | ||||
| import kotlin.text.RegexOption.* | ||||
| 
 | ||||
| class RegexTest { | ||||
| 
 | ||||
|     @Test | ||||
|     fun whenRegexIsInstantiated_thenIsEqualToToRegexMethod() { | ||||
|         val pattern = """a([bc]+)d?\\""" | ||||
| 
 | ||||
|         assertEquals(Regex.fromLiteral(pattern).pattern, pattern) | ||||
|         assertEquals(pattern, Regex(pattern).pattern) | ||||
|         assertEquals(pattern, pattern.toRegex().pattern) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun whenRegexMatches_thenResultIsTrue() { | ||||
|         val regex = """a([bc]+)d?""".toRegex() | ||||
| 
 | ||||
|         assertTrue(regex.containsMatchIn("xabcdy")) | ||||
|         assertTrue(regex.matches("abcd")) | ||||
|         assertFalse(regex matches "xabcdy") | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun givenCompletelyMatchingRegex_whenMatchResult_thenDestructuring() { | ||||
|         val regex = """a([bc]+)d?""".toRegex() | ||||
| 
 | ||||
|         assertNull(regex.matchEntire("xabcdy")) | ||||
| 
 | ||||
|         val matchResult = regex.matchEntire("abbccbbd") | ||||
| 
 | ||||
|         assertNotNull(matchResult) | ||||
|         assertEquals(matchResult!!.value, matchResult.groupValues[0]) | ||||
|         assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1)) | ||||
|         assertEquals("bbccbb", matchResult.destructured.component1()) | ||||
|         assertNull(matchResult.next()) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun givenPartiallyMatchingRegex_whenMatchResult_thenGroups() { | ||||
|         val regex = """a([bc]+)d?""".toRegex() | ||||
|         var matchResult = regex.find("abcb abbd") | ||||
| 
 | ||||
|         assertNotNull(matchResult) | ||||
|         assertEquals(matchResult!!.value, matchResult.groupValues[0]) | ||||
|         assertEquals("abcb", matchResult.value) | ||||
|         assertEquals(IntRange(0, 3), matchResult.range) | ||||
|         assertEquals(listOf("abcb", "bcb"), matchResult.groupValues) | ||||
|         assertEquals(matchResult.destructured.toList(), matchResult.groupValues.drop(1)) | ||||
| 
 | ||||
|         matchResult = matchResult.next() | ||||
| 
 | ||||
|         assertNotNull(matchResult) | ||||
|         assertEquals("abbd", matchResult!!.value) | ||||
|         assertEquals("bb", matchResult.groupValues[1]) | ||||
| 
 | ||||
|         matchResult = matchResult.next() | ||||
| 
 | ||||
|         assertNull(matchResult) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun givenPartiallyMatchingRegex_whenMatchResult_thenDestructuring() { | ||||
|         val regex = """([\w\s]+) is (\d+) years old""".toRegex() | ||||
|         val matchResult = regex.find("Mickey Mouse is 95 years old") | ||||
|         val (name, age) = matchResult!!.destructured | ||||
| 
 | ||||
|         assertEquals("Mickey Mouse", name) | ||||
|         assertEquals("95", age) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun givenNonMatchingRegex_whenFindCalled_thenNull() { | ||||
|         val regex = """a([bc]+)d?""".toRegex() | ||||
|         val matchResult = regex.find("foo") | ||||
| 
 | ||||
|         assertNull(matchResult) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun givenNonMatchingRegex_whenFindAllCalled_thenEmptySet() { | ||||
|         val regex = """a([bc]+)d?""".toRegex() | ||||
|         val matchResults = regex.findAll("foo") | ||||
| 
 | ||||
|         assertNotNull(matchResults) | ||||
|         assertTrue(matchResults.none()) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun whenReplace_thenReplacement() { | ||||
|         val regex = """(red|green|blue)""".toRegex() | ||||
|         val beautiful = "Roses are red, Violets are blue" | ||||
|         val grim = regex.replace(beautiful, "dark") | ||||
|         val shiny = regex.replaceFirst(beautiful, "rainbow") | ||||
| 
 | ||||
|         assertEquals("Roses are dark, Violets are dark", grim) | ||||
|         assertEquals("Roses are rainbow, Violets are blue", shiny) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun whenComplexReplace_thenReplacement() { | ||||
|         val regex = """(red|green|blue)""".toRegex() | ||||
|         val beautiful = "Roses are red, Violets are blue" | ||||
|         val reallyBeautiful = regex.replace(beautiful) { | ||||
|             matchResult ->  matchResult.value.toUpperCase() + "!" | ||||
|         } | ||||
| 
 | ||||
|         assertEquals("Roses are RED!, Violets are BLUE!", reallyBeautiful) | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun whenSplit_thenList() { | ||||
|         val regex = """\W+""".toRegex() | ||||
|         val beautiful = "Roses are red, Violets are blue" | ||||
| 
 | ||||
|         assertEquals(listOf("Roses", "are", "red", "Violets", "are", "blue"), regex.split(beautiful)) | ||||
|         assertEquals(listOf("Roses", "are", "red", "Violets are blue"), regex.split(beautiful, 4)) | ||||
|         assertEquals(regex.toPattern().split(beautiful).asList(), regex.split(beautiful)) | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package org.baeldung.guava.memoizer; | ||||
| 
 | ||||
| import java.math.BigInteger; | ||||
| import java.util.Random; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| public class CostlySupplier { | ||||
| 
 | ||||
|     public static BigInteger generateBigNumber() { | ||||
|         try { | ||||
|             TimeUnit.SECONDS.sleep(2); | ||||
|         } catch (InterruptedException e) { | ||||
|         } | ||||
|         return new BigInteger("12345"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,22 @@ | ||||
| package org.baeldung.guava.memoizer; | ||||
| 
 | ||||
| import com.google.common.cache.CacheBuilder; | ||||
| import com.google.common.cache.CacheLoader; | ||||
| import com.google.common.cache.LoadingCache; | ||||
| 
 | ||||
| import java.math.BigInteger; | ||||
| 
 | ||||
| public class Factorial { | ||||
| 
 | ||||
|     private static LoadingCache<Integer, BigInteger> memo = CacheBuilder.newBuilder() | ||||
|             .build(CacheLoader.from(Factorial::getFactorial)); | ||||
| 
 | ||||
|     public static BigInteger getFactorial(int n) { | ||||
|         if (n == 0) { | ||||
|             return BigInteger.ONE; | ||||
|         } else { | ||||
|             return BigInteger.valueOf(n).multiply(memo.getUnchecked(n - 1)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| package org.baeldung.guava.memoizer; | ||||
| 
 | ||||
| import com.google.common.cache.CacheBuilder; | ||||
| import com.google.common.cache.CacheLoader; | ||||
| import com.google.common.cache.LoadingCache; | ||||
| 
 | ||||
| import java.math.BigInteger; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| public class FibonacciSequence { | ||||
| 
 | ||||
|     private static LoadingCache<Integer, BigInteger> memo = CacheBuilder.newBuilder() | ||||
|             .maximumSize(100) | ||||
|             .build(CacheLoader.from(FibonacciSequence::getFibonacciNumber)); | ||||
| 
 | ||||
|     public static BigInteger getFibonacciNumber(int n) { | ||||
|         if (n == 0) { | ||||
|             return BigInteger.ZERO; | ||||
|         } else if (n == 1) { | ||||
|             return BigInteger.ONE; | ||||
|         } else { | ||||
|             return memo.getUnchecked(n - 1).add(memo.getUnchecked(n - 2)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,92 @@ | ||||
| package org.baeldung.guava; | ||||
| 
 | ||||
| import com.google.common.base.Suppliers; | ||||
| import org.baeldung.guava.memoizer.CostlySupplier; | ||||
| import org.baeldung.guava.memoizer.Factorial; | ||||
| import org.baeldung.guava.memoizer.FibonacciSequence; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.math.BigInteger; | ||||
| import java.time.Duration; | ||||
| import java.time.Instant; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import java.util.function.Supplier; | ||||
| 
 | ||||
| import static org.hamcrest.core.Is.is; | ||||
| import static org.hamcrest.core.IsEqual.equalTo; | ||||
| import static org.hamcrest.number.IsCloseTo.closeTo; | ||||
| import static org.junit.Assert.assertThat; | ||||
| 
 | ||||
| public class GuavaMemoizerUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInteger_whenGetFibonacciNumber_thenShouldCalculateFibonacciNumber() { | ||||
|         // given | ||||
|         int n = 95; | ||||
| 
 | ||||
|         // when | ||||
|         BigInteger fibonacciNumber = FibonacciSequence.getFibonacciNumber(n); | ||||
| 
 | ||||
|         // then | ||||
|         BigInteger expectedFibonacciNumber = new BigInteger("31940434634990099905"); | ||||
|         assertThat(fibonacciNumber, is(equalTo(expectedFibonacciNumber))); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInteger_whenGetFactorial_thenShouldCalculateFactorial() { | ||||
|         // given | ||||
|         int n = 95; | ||||
| 
 | ||||
|         // when | ||||
|         BigInteger factorial = Factorial.getFactorial(n); | ||||
| 
 | ||||
|         // then | ||||
|         BigInteger expectedFactorial = new BigInteger("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000"); | ||||
|         assertThat(factorial, is(equalTo(expectedFactorial))); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenMemoizedSupplier_whenGet_thenSubsequentGetsAreFast() { | ||||
|         // given | ||||
|         Supplier<BigInteger> memoizedSupplier; | ||||
|         memoizedSupplier = Suppliers.memoize(CostlySupplier::generateBigNumber); | ||||
| 
 | ||||
|         // when | ||||
|         BigInteger expectedValue = new BigInteger("12345"); | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 2000D); | ||||
| 
 | ||||
|         // then | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 0D); | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 0D); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenMemoizedSupplierWithExpiration_whenGet_thenSubsequentGetsBeforeExpiredAreFast() throws InterruptedException { | ||||
|         // given | ||||
|         Supplier<BigInteger> memoizedSupplier; | ||||
|         memoizedSupplier = Suppliers.memoizeWithExpiration(CostlySupplier::generateBigNumber, 3, TimeUnit.SECONDS); | ||||
| 
 | ||||
|         // when | ||||
|         BigInteger expectedValue = new BigInteger("12345"); | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 2000D); | ||||
| 
 | ||||
|         // then | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 0D); | ||||
|         // add one more second until memoized Supplier is evicted from memory | ||||
|         TimeUnit.SECONDS.sleep(1); | ||||
|         assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 2000D); | ||||
|     } | ||||
| 
 | ||||
|     private <T> void assertSupplierGetExecutionResultAndDuration(Supplier<T> supplier, | ||||
|                                                                  T expectedValue, | ||||
|                                                                  double expectedDurationInMs) { | ||||
|         Instant start = Instant.now(); | ||||
|         T value = supplier.get(); | ||||
|         Long durationInMs = Duration.between(start, Instant.now()).toMillis(); | ||||
|         double marginOfErrorInMs = 100D; | ||||
| 
 | ||||
|         assertThat(value, is(equalTo(expectedValue))); | ||||
|         assertThat(durationInMs.doubleValue(), is(closeTo(expectedDurationInMs, marginOfErrorInMs))); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -81,6 +81,7 @@ public class HibernateUtil { | ||||
|         metadataSources.addAnnotatedClass(Bag.class); | ||||
|         metadataSources.addAnnotatedClass(PointEntity.class); | ||||
|         metadataSources.addAnnotatedClass(PolygonEntity.class); | ||||
|         metadataSources.addAnnotatedClass(com.baeldung.hibernate.pojo.Person.class); | ||||
| 
 | ||||
|         Metadata metadata = metadataSources.buildMetadata(); | ||||
|         return metadata.getSessionFactoryBuilder() | ||||
|  | ||||
| @ -0,0 +1,43 @@ | ||||
| package com.baeldung.hibernate.converters; | ||||
| 
 | ||||
| import javax.persistence.AttributeConverter; | ||||
| import javax.persistence.Converter; | ||||
| 
 | ||||
| import com.baeldung.hibernate.pojo.PersonName; | ||||
| 
 | ||||
| @Converter | ||||
| public class PersonNameConverter implements AttributeConverter<PersonName, String> { | ||||
| 
 | ||||
|     private static final String SEPARATOR = ", "; | ||||
| 
 | ||||
|     @Override | ||||
|     public String convertToDatabaseColumn(PersonName person) { | ||||
|         StringBuilder sb = new StringBuilder(); | ||||
|         if (person.getSurname() != null) { | ||||
|             sb.append(person.getSurname()); | ||||
|             sb.append(SEPARATOR); | ||||
|         } | ||||
| 
 | ||||
|         if (person.getName() != null) { | ||||
|             sb.append(person.getName()); | ||||
|         } | ||||
| 
 | ||||
|         return sb.toString(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public PersonName convertToEntityAttribute(String dbPerson) { | ||||
|         String[] pieces = dbPerson.split(SEPARATOR); | ||||
| 
 | ||||
|         if (pieces == null || pieces.length != 2) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         PersonName personName = new PersonName(); | ||||
|         personName.setSurname(pieces[0]); | ||||
|         personName.setName(pieces[1]); | ||||
| 
 | ||||
|         return personName; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -9,7 +9,7 @@ import org.hibernate.Interceptor; | ||||
| import org.hibernate.Transaction; | ||||
| import org.hibernate.type.Type; | ||||
| 
 | ||||
| public class CustomInterceptorImpl implements Interceptor { | ||||
| public class CustomInterceptorImpl implements Interceptor, Serializable { | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { | ||||
|  | ||||
| @ -0,0 +1,32 @@ | ||||
| package com.baeldung.hibernate.pojo; | ||||
| 
 | ||||
| import javax.persistence.Convert; | ||||
| import javax.persistence.Entity; | ||||
| import javax.persistence.GeneratedValue; | ||||
| import javax.persistence.Id; | ||||
| 
 | ||||
| import com.baeldung.hibernate.converters.PersonNameConverter; | ||||
| 
 | ||||
| @Entity(name = "PersonTable") | ||||
| public class Person { | ||||
| 
 | ||||
|     @Id | ||||
|     @GeneratedValue | ||||
|     private Long id; | ||||
| 
 | ||||
|     @Convert(converter = PersonNameConverter.class) | ||||
|     private PersonName personName; | ||||
| 
 | ||||
|     public PersonName getPersonName() { | ||||
|         return personName; | ||||
|     } | ||||
| 
 | ||||
|     public void setPersonName(PersonName personName) { | ||||
|         this.personName = personName; | ||||
|     } | ||||
| 
 | ||||
|     public Long getId() { | ||||
|         return id; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| package com.baeldung.hibernate.pojo; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| public class PersonName implements Serializable { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 7883094644631050150L; | ||||
| 
 | ||||
|     private String name; | ||||
| 
 | ||||
|     private String surname; | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public String getSurname() { | ||||
|         return surname; | ||||
|     } | ||||
| 
 | ||||
|     public void setSurname(String surname) { | ||||
|         this.surname = surname; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| package com.baeldung.hibernate.converter; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import org.hibernate.Session; | ||||
| import org.hibernate.Transaction; | ||||
| import org.junit.After; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import com.baeldung.hibernate.HibernateUtil; | ||||
| import com.baeldung.hibernate.pojo.Person; | ||||
| import com.baeldung.hibernate.pojo.PersonName; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| public class PersonNameConverterTest { | ||||
| 
 | ||||
|     private Session session; | ||||
|     private Transaction transaction; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() throws IOException { | ||||
|         session = HibernateUtil.getSessionFactory() | ||||
|             .openSession(); | ||||
|         transaction = session.beginTransaction(); | ||||
| 
 | ||||
|         session.createNativeQuery("delete from personTable") | ||||
|             .executeUpdate(); | ||||
| 
 | ||||
|         transaction.commit(); | ||||
|         transaction = session.beginTransaction(); | ||||
|     } | ||||
| 
 | ||||
|     @After | ||||
|     public void tearDown() { | ||||
|         transaction.rollback(); | ||||
|         session.close(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenPersonName_WhenSaving_ThenNameAndSurnameConcat() { | ||||
|         final String name = "name"; | ||||
|         final String surname = "surname"; | ||||
| 
 | ||||
|         PersonName personName = new PersonName(); | ||||
|         personName.setName(name); | ||||
|         personName.setSurname(surname); | ||||
| 
 | ||||
|         Person person = new Person(); | ||||
|         person.setPersonName(personName); | ||||
| 
 | ||||
|         Long id = (Long) session.save(person); | ||||
| 
 | ||||
|         session.flush(); | ||||
|         session.clear(); | ||||
| 
 | ||||
|         String dbPersonName = (String) session.createNativeQuery("select p.personName from PersonTable p where p.id = :id") | ||||
|             .setParameter("id", id) | ||||
|             .getSingleResult(); | ||||
| 
 | ||||
|         assertEquals(surname + ", " + name, dbPersonName); | ||||
| 
 | ||||
|         Person dbPerson = session.createNativeQuery("select * from PersonTable p where p.id = :id", Person.class) | ||||
|             .setParameter("id", id) | ||||
|             .getSingleResult(); | ||||
| 
 | ||||
|         assertEquals(dbPerson.getPersonName() | ||||
|             .getName(), name); | ||||
|         assertEquals(dbPerson.getPersonName() | ||||
|             .getSurname(), surname); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -2,7 +2,6 @@ | ||||
| 
 | ||||
| ### Relevant Article: | ||||
| - [Introduction to using InfluxDB with Java](http://www.baeldung.com/using-influxdb-with-java/) | ||||
| - [Using InfluxDB with Java](http://www.baeldung.com/java-influxdb) | ||||
| 
 | ||||
| ### Overview | ||||
| This Maven project contains the Java code for the article linked above. | ||||
|  | ||||
| @ -8,7 +8,6 @@ import org.influxdb.dto.*; | ||||
| import org.influxdb.impl.InfluxDBResultMapper; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.List; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| @ -103,7 +102,7 @@ public class InfluxDBConnectionLiveTest { | ||||
|         // another brief pause. | ||||
|         Thread.sleep(10); | ||||
| 
 | ||||
|         List<MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung"); | ||||
|         List<com.baeldung.influxdb.MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung"); | ||||
| 
 | ||||
|         assertEquals(10, memoryPointList.size()); | ||||
| 
 | ||||
|  | ||||
| @ -129,7 +129,7 @@ | ||||
| 
 | ||||
|     <properties> | ||||
|         <!-- marshalling --> | ||||
|         <jackson.version>2.9.2</jackson.version> | ||||
|         <jackson.version>2.9.4</jackson.version> | ||||
| 
 | ||||
|         <!-- util --> | ||||
|         <guava.version>19.0</guava.version> | ||||
|  | ||||
| @ -6,10 +6,11 @@ | ||||
|     <version>0.1-SNAPSHOT</version> | ||||
| 
 | ||||
|     <properties> | ||||
|         <validation-api.version>2.0.0.Final</validation-api.version> | ||||
|         <hibernate-validator.version>6.0.2.Final</hibernate-validator.version> | ||||
|         <validation-api.version>2.0.1.Final</validation-api.version> | ||||
|         <hibernate-validator.version>6.0.7.Final</hibernate-validator.version> | ||||
|         <javax.el-api.version>3.0.0</javax.el-api.version> | ||||
|         <javax.el.version>2.2.6</javax.el.version> | ||||
|         <org.springframework.version>5.0.2.RELEASE</org.springframework.version> | ||||
|     </properties> | ||||
| 
 | ||||
| 
 | ||||
| @ -21,12 +22,6 @@ | ||||
| 
 | ||||
|     <dependencies> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>javax.validation</groupId> | ||||
|             <artifactId>validation-api</artifactId> | ||||
|             <version>${validation-api.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.hibernate</groupId> | ||||
|             <artifactId>hibernate-validator</artifactId> | ||||
| @ -50,6 +45,16 @@ | ||||
|             <artifactId>javax.el</artifactId> | ||||
|             <version>${javax.el.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework</groupId> | ||||
|             <artifactId>spring-context</artifactId> | ||||
|             <version>${org.springframework.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework</groupId> | ||||
|             <artifactId>spring-test</artifactId> | ||||
|             <version>${org.springframework.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|     </dependencies> | ||||
| 
 | ||||
|  | ||||
| @ -0,0 +1,38 @@ | ||||
| package org.baeldung.javaxval.methodvalidation; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.model.Customer; | ||||
| import org.baeldung.javaxval.methodvalidation.model.Reservation; | ||||
| import org.springframework.beans.factory.config.BeanDefinition; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.Scope; | ||||
| import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; | ||||
| 
 | ||||
| import java.time.LocalDate; | ||||
| 
 | ||||
| @Configuration | ||||
| @ComponentScan({ "org.baeldung.javaxval.methodvalidation.model" }) | ||||
| public class MethodValidationConfig { | ||||
| 
 | ||||
|     @Bean | ||||
|     public MethodValidationPostProcessor methodValidationPostProcessor() { | ||||
|         return new MethodValidationPostProcessor(); | ||||
|     } | ||||
| 
 | ||||
|     @Bean("customer") | ||||
|     @Scope(BeanDefinition.SCOPE_PROTOTYPE) | ||||
|     public Customer customer(String firstName, String lastName) { | ||||
| 
 | ||||
|         Customer customer = new Customer(firstName, lastName); | ||||
|         return customer; | ||||
|     } | ||||
| 
 | ||||
|     @Bean("reservation") | ||||
|     @Scope(BeanDefinition.SCOPE_PROTOTYPE) | ||||
|     public Reservation reservation(LocalDate begin, LocalDate end, Customer customer, int room) { | ||||
| 
 | ||||
|         Reservation reservation = new Reservation(begin, end, customer, room); | ||||
|         return reservation; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.constraints; | ||||
| 
 | ||||
| import javax.validation.ConstraintValidator; | ||||
| import javax.validation.ConstraintValidatorContext; | ||||
| import javax.validation.constraintvalidation.SupportedValidationTarget; | ||||
| import javax.validation.constraintvalidation.ValidationTarget; | ||||
| import java.time.LocalDate; | ||||
| 
 | ||||
| @SupportedValidationTarget(ValidationTarget.PARAMETERS) | ||||
| public class ConsistentDateParameterValidator implements ConstraintValidator<ConsistentDateParameters, Object[]> { | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isValid(Object[] value, ConstraintValidatorContext context) { | ||||
| 
 | ||||
|         if (value[0] == null || value[1] == null) { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) { | ||||
|             throw new IllegalArgumentException("Illegal method signature, expected two parameters of type LocalDate."); | ||||
|         } | ||||
| 
 | ||||
|         return ((LocalDate) value[0]).isAfter(LocalDate.now()) && ((LocalDate) value[0]).isBefore((LocalDate) value[1]); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.constraints; | ||||
| 
 | ||||
| import javax.validation.Constraint; | ||||
| import javax.validation.Payload; | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.Target; | ||||
| 
 | ||||
| import static java.lang.annotation.ElementType.*; | ||||
| import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||||
| 
 | ||||
| @Constraint(validatedBy = ConsistentDateParameterValidator.class) | ||||
| @Target({ METHOD, CONSTRUCTOR }) | ||||
| @Retention(RUNTIME) | ||||
| @Documented | ||||
| public @interface ConsistentDateParameters { | ||||
| 
 | ||||
|     String message() default "End date must be after begin date and both must be in the future"; | ||||
| 
 | ||||
|     Class<?>[] groups() default {}; | ||||
| 
 | ||||
|     Class<? extends Payload>[] payload() default {}; | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.constraints; | ||||
| 
 | ||||
| import javax.validation.Constraint; | ||||
| import javax.validation.Payload; | ||||
| import java.lang.annotation.Documented; | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.Target; | ||||
| 
 | ||||
| import static java.lang.annotation.ElementType.CONSTRUCTOR; | ||||
| import static java.lang.annotation.ElementType.METHOD; | ||||
| import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||||
| 
 | ||||
| @Constraint(validatedBy = ValidReservationValidator.class) | ||||
| @Target({ METHOD, CONSTRUCTOR }) | ||||
| @Retention(RUNTIME) | ||||
| @Documented | ||||
| public @interface ValidReservation { | ||||
| 
 | ||||
|     String message() default "End date must be after begin date and both must be in the future, room number must be bigger than 0"; | ||||
| 
 | ||||
|     Class<?>[] groups() default {}; | ||||
| 
 | ||||
|     Class<? extends Payload>[] payload() default {}; | ||||
| } | ||||
| @ -0,0 +1,32 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.constraints; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.model.Reservation; | ||||
| 
 | ||||
| import javax.validation.ConstraintValidator; | ||||
| import javax.validation.ConstraintValidatorContext; | ||||
| import java.time.LocalDate; | ||||
| 
 | ||||
| public class ValidReservationValidator implements ConstraintValidator<ValidReservation, Reservation> { | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isValid(Reservation reservation, ConstraintValidatorContext context) { | ||||
| 
 | ||||
|         if (reservation == null) { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         if (!(reservation instanceof Reservation)) { | ||||
|             throw new IllegalArgumentException("Illegal method signature, expected parameter of type Reservation."); | ||||
|         } | ||||
| 
 | ||||
|         if (reservation.getBegin() == null || reservation.getEnd() == null || reservation.getCustomer() == null) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return (reservation.getBegin() | ||||
|             .isAfter(LocalDate.now()) | ||||
|             && reservation.getBegin() | ||||
|                 .isBefore(reservation.getEnd()) | ||||
|             && reservation.getRoom() > 0); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,41 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.model; | ||||
| 
 | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| 
 | ||||
| import javax.validation.constraints.NotNull; | ||||
| import javax.validation.constraints.Size; | ||||
| 
 | ||||
| @Validated | ||||
| public class Customer { | ||||
| 
 | ||||
|     @Size(min = 5, max = 200) | ||||
|     private String firstName; | ||||
| 
 | ||||
|     @Size(min = 5, max = 200) | ||||
|     private String lastName; | ||||
| 
 | ||||
|     public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) @NotNull String lastName) { | ||||
|         this.firstName = firstName; | ||||
|         this.lastName = lastName; | ||||
|     } | ||||
| 
 | ||||
|     public Customer() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public String getFirstName() { | ||||
|         return firstName; | ||||
|     } | ||||
| 
 | ||||
|     public void setFirstName(String firstName) { | ||||
|         this.firstName = firstName; | ||||
|     } | ||||
| 
 | ||||
|     public String getLastName() { | ||||
|         return lastName; | ||||
|     } | ||||
| 
 | ||||
|     public void setLastName(String lastName) { | ||||
|         this.lastName = lastName; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,64 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.model; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters; | ||||
| import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| 
 | ||||
| import javax.validation.Valid; | ||||
| import javax.validation.constraints.Positive; | ||||
| import java.time.LocalDate; | ||||
| 
 | ||||
| @Validated | ||||
| public class Reservation { | ||||
| 
 | ||||
|     private LocalDate begin; | ||||
| 
 | ||||
|     private LocalDate end; | ||||
| 
 | ||||
|     @Valid | ||||
|     private Customer customer; | ||||
| 
 | ||||
|     @Positive | ||||
|     private int room; | ||||
| 
 | ||||
|     @ConsistentDateParameters | ||||
|     @ValidReservation | ||||
|     public Reservation(LocalDate begin, LocalDate end, Customer customer, int room) { | ||||
|         this.begin = begin; | ||||
|         this.end = end; | ||||
|         this.customer = customer; | ||||
|         this.room = room; | ||||
|     } | ||||
| 
 | ||||
|     public LocalDate getBegin() { | ||||
|         return begin; | ||||
|     } | ||||
| 
 | ||||
|     public void setBegin(LocalDate begin) { | ||||
|         this.begin = begin; | ||||
|     } | ||||
| 
 | ||||
|     public LocalDate getEnd() { | ||||
|         return end; | ||||
|     } | ||||
| 
 | ||||
|     public void setEnd(LocalDate end) { | ||||
|         this.end = end; | ||||
|     } | ||||
| 
 | ||||
|     public Customer getCustomer() { | ||||
|         return customer; | ||||
|     } | ||||
| 
 | ||||
|     public void setCustomer(Customer customer) { | ||||
|         this.customer = customer; | ||||
|     } | ||||
| 
 | ||||
|     public int getRoom() { | ||||
|         return room; | ||||
|     } | ||||
| 
 | ||||
|     public void setRoom(int room) { | ||||
|         this.room = room; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,50 @@ | ||||
| package org.baeldung.javaxval.methodvalidation.model; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.constraints.ConsistentDateParameters; | ||||
| import org.baeldung.javaxval.methodvalidation.constraints.ValidReservation; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| 
 | ||||
| import javax.validation.Valid; | ||||
| import javax.validation.constraints.*; | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Controller | ||||
| @Validated | ||||
| public class ReservationManagement { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private ApplicationContext applicationContext; | ||||
| 
 | ||||
|     @ConsistentDateParameters | ||||
|     public void createReservation(LocalDate begin, LocalDate end, @NotNull Customer customer) { | ||||
| 
 | ||||
|         // ... | ||||
|     } | ||||
| 
 | ||||
|     public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer) { | ||||
| 
 | ||||
|         // ... | ||||
|     } | ||||
| 
 | ||||
|     public void createReservation(@Valid Reservation reservation) { | ||||
| 
 | ||||
|         // ... | ||||
|     } | ||||
| 
 | ||||
|     @NotNull | ||||
|     @Size(min = 1) | ||||
|     public List<@NotNull Customer> getAllCustomers() { | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Valid | ||||
|     public Reservation getReservationById(int id) { | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,97 @@ | ||||
| package org.baeldung.javaxval.methodvalidation; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.model.Customer; | ||||
| import org.baeldung.javaxval.methodvalidation.model.Reservation; | ||||
| import org.baeldung.javaxval.methodvalidation.model.ReservationManagement; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.rules.ExpectedException; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.test.context.ContextConfiguration; | ||||
| import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||
| import org.springframework.test.context.support.AnnotationConfigContextLoader; | ||||
| 
 | ||||
| import javax.validation.ConstraintViolationException; | ||||
| import java.time.LocalDate; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @RunWith(SpringJUnit4ClassRunner.class) | ||||
| @ContextConfiguration(classes = { MethodValidationConfig.class }, loader = AnnotationConfigContextLoader.class) | ||||
| public class ContainerValidationIntegrationTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     ReservationManagement reservationManagement; | ||||
| 
 | ||||
|     @Rule | ||||
|     public final ExpectedException exception = ExpectedException.none(); | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidMethodParameters_thenConstraintViolationException() { | ||||
| 
 | ||||
|         exception.expect(ConstraintViolationException.class); | ||||
|         reservationManagement.createReservation(LocalDate.now(), 0, null); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidMethodParameters_thenNoException() { | ||||
| 
 | ||||
|         reservationManagement.createReservation(LocalDate.now() | ||||
|             .plusDays(1), 1, new Customer("William", "Smith")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithInvalidParameters_thenConstraintViolationException() { | ||||
| 
 | ||||
|         exception.expect(ConstraintViolationException.class); | ||||
|         reservationManagement.createReservation(LocalDate.now(), LocalDate.now(), null); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithValidParameters_thenNoException() { | ||||
| 
 | ||||
|         reservationManagement.createReservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             new Customer("William", "Smith")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidReturnValue_thenConstraintViolationException() { | ||||
| 
 | ||||
|         exception.expect(ConstraintViolationException.class); | ||||
|         List<Customer> list = reservationManagement.getAllCustomers(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidCascadedValue_thenConstraintViolationException() { | ||||
| 
 | ||||
|         Customer customer = new Customer(); | ||||
|         customer.setFirstName("John"); | ||||
|         customer.setLastName("Doe"); | ||||
|         Reservation reservation = new Reservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             customer, 1); | ||||
| 
 | ||||
|         exception.expect(ConstraintViolationException.class); | ||||
|         reservationManagement.createReservation(reservation); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidCascadedValue_thenCNoException() { | ||||
| 
 | ||||
|         Customer customer = new Customer(); | ||||
|         customer.setFirstName("William"); | ||||
|         customer.setLastName("Smith"); | ||||
|         Reservation reservation = new Reservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             customer, 1); | ||||
| 
 | ||||
|         reservationManagement.createReservation(reservation); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,209 @@ | ||||
| package org.baeldung.javaxval.methodvalidation; | ||||
| 
 | ||||
| import org.baeldung.javaxval.methodvalidation.model.Customer; | ||||
| import org.baeldung.javaxval.methodvalidation.model.Reservation; | ||||
| import org.baeldung.javaxval.methodvalidation.model.ReservationManagement; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import static org.junit.Assert.*; | ||||
| 
 | ||||
| import javax.validation.ConstraintViolation; | ||||
| import javax.validation.Validation; | ||||
| import javax.validation.ValidatorFactory; | ||||
| import javax.validation.executable.ExecutableValidator; | ||||
| import java.lang.reflect.Constructor; | ||||
| import java.lang.reflect.Method; | ||||
| import java.time.LocalDate; | ||||
| import java.util.Collections; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| public class ValidationIntegrationTest { | ||||
| 
 | ||||
|     private ExecutableValidator executableValidator; | ||||
| 
 | ||||
|     @Before | ||||
|     public void getExecutableValidator() { | ||||
| 
 | ||||
|         ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); | ||||
|         this.executableValidator = factory.getValidator() | ||||
|             .forExecutables(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidMethodParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class); | ||||
|         Object[] parameterValues = { LocalDate.now(), 0, null }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(3, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidMethodParameters_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, int.class, Customer.class); | ||||
|         Object[] parameterValues = { LocalDate.now() | ||||
|             .plusDays(1), 1, new Customer("John", "Doe") }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithInvalidParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class); | ||||
|         Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("John", "Doe") }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(1, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithValidParameters_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", LocalDate.class, LocalDate.class, Customer.class); | ||||
|         Object[] parameterValues = { LocalDate.now() | ||||
|             .plusDays(1), | ||||
|                 LocalDate.now() | ||||
|                     .plusDays(2), | ||||
|                 new Customer("John", "Doe") }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Customer> constructor = Customer.class.getConstructor(String.class, String.class); | ||||
|         Object[] parameterValues = { "John", "Doe" }; | ||||
|         Set<ConstraintViolation<Customer>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); | ||||
| 
 | ||||
|         assertEquals(2, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Customer> constructor = Customer.class.getConstructor(String.class, String.class); | ||||
|         Object[] parameterValues = { "William", "Smith" }; | ||||
|         Set<ConstraintViolation<Customer>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithInvalidConstructorParameters_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); | ||||
|         Object[] parameterValues = { LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 1 }; | ||||
|         Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); | ||||
| 
 | ||||
|         assertEquals(1, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCrossParameterValidationWithValidConstructorParameters_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); | ||||
|         Object[] parameterValues = { LocalDate.now() | ||||
|             .plusDays(1), | ||||
|                 LocalDate.now() | ||||
|                     .plusDays(2), | ||||
|                 new Customer("William", "Smith"), 1 }; | ||||
|         Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorParameters(constructor, parameterValues); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("getAllCustomers"); | ||||
|         Object returnValue = Collections.<Customer> emptyList(); | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateReturnValue(object, method, returnValue); | ||||
| 
 | ||||
|         assertEquals(1, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidReturnValue_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("getAllCustomers"); | ||||
|         Object returnValue = Collections.singletonList(new Customer("William", "Smith")); | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateReturnValue(object, method, returnValue); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidConstructorReturnValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); | ||||
|         Reservation createdObject = new Reservation(LocalDate.now(), LocalDate.now(), new Customer("William", "Smith"), 0); | ||||
|         Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject); | ||||
| 
 | ||||
|         assertEquals(1, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidConstructorReturnValue_thenZeroVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         Constructor<Reservation> constructor = Reservation.class.getConstructor(LocalDate.class, LocalDate.class, Customer.class, int.class); | ||||
|         Reservation createdObject = new Reservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             new Customer("William", "Smith"), 1); | ||||
|         Set<ConstraintViolation<Reservation>> violations = executableValidator.validateConstructorReturnValue(constructor, createdObject); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithInvalidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class); | ||||
|         Customer customer = new Customer(); | ||||
|         customer.setFirstName("John"); | ||||
|         customer.setLastName("Doe"); | ||||
|         Reservation reservation = new Reservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             customer, 1); | ||||
|         Object[] parameterValues = { reservation }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(2, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidationWithValidCascadedValue_thenCorrectNumberOfVoilations() throws NoSuchMethodException { | ||||
| 
 | ||||
|         ReservationManagement object = new ReservationManagement(); | ||||
|         Method method = ReservationManagement.class.getMethod("createReservation", Reservation.class); | ||||
|         Customer customer = new Customer(); | ||||
|         customer.setFirstName("William"); | ||||
|         customer.setLastName("Smith"); | ||||
|         Reservation reservation = new Reservation(LocalDate.now() | ||||
|             .plusDays(1), | ||||
|             LocalDate.now() | ||||
|                 .plusDays(2), | ||||
|             customer, 1); | ||||
|         Object[] parameterValues = { reservation }; | ||||
|         Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues); | ||||
| 
 | ||||
|         assertEquals(0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										15
									
								
								jgroups/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								jgroups/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| ## Reliable Messaging with JGroups Tutorial Project | ||||
| 
 | ||||
| ### Relevant Article: | ||||
| - [Reliable Messaging with JGroups](http://www.baeldung.com/reliable-messaging-with-jgroups/) | ||||
| 
 | ||||
| ### Overview | ||||
| This Maven project contains the Java code for the article linked above. | ||||
| 
 | ||||
| ### Package Organization | ||||
| Java classes for the intro tutorial are in the org.baeldung.jgroups package. | ||||
| 
 | ||||
| 
 | ||||
| ### Running the tests | ||||
| 
 | ||||
| ``` | ||||
							
								
								
									
										36
									
								
								jgroups/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								jgroups/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>jgroups</artifactId> | ||||
|     <version>0.1-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|     <name>jgroups</name> | ||||
|     <description>Reliable Messaging with JGroups Tutorial</description> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>com.baeldung</groupId> | ||||
|         <artifactId>parent-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.jgroups</groupId> | ||||
|             <artifactId>jgroups</artifactId> | ||||
|             <version>4.0.10.Final</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>commons-cli</groupId> | ||||
|             <artifactId>commons-cli</artifactId> | ||||
|             <version>1.4</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <properties> | ||||
|         <java.version>1.8</java.version> | ||||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
							
								
								
									
										212
									
								
								jgroups/src/main/java/com/baeldung/jgroups/JGroupsMessenger.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								jgroups/src/main/java/com/baeldung/jgroups/JGroupsMessenger.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,212 @@ | ||||
| package com.baeldung.jgroups; | ||||
| 
 | ||||
| import org.apache.commons.cli.*; | ||||
| import org.jgroups.*; | ||||
| import org.jgroups.util.Util; | ||||
| 
 | ||||
| import java.io.*; | ||||
| import java.util.List; | ||||
| import java.util.Optional; | ||||
| 
 | ||||
| public class JGroupsMessenger extends ReceiverAdapter { | ||||
| 
 | ||||
|     private JChannel channel; | ||||
|     private String userName; | ||||
|     private String clusterName; | ||||
|     private View lastView; | ||||
|     private boolean running = true; | ||||
| 
 | ||||
|     // Our shared state | ||||
|     private Integer messageCount = 0; | ||||
| 
 | ||||
|     /** | ||||
|      * Connect to a JGroups cluster using command line options | ||||
|      * @param args command line arguments | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     private void start(String[] args) throws Exception { | ||||
|         processCommandline(args); | ||||
| 
 | ||||
|         // Create the channel | ||||
|         // This file could be moved, or made a command line option. | ||||
|         channel = new JChannel("src/main/resources/udp.xml"); | ||||
| 
 | ||||
|         // Set a name | ||||
|         channel.name(userName); | ||||
| 
 | ||||
|         // Register for callbacks | ||||
|         channel.setReceiver(this); | ||||
| 
 | ||||
|         // Ignore our messages | ||||
|         channel.setDiscardOwnMessages(true); | ||||
| 
 | ||||
|         // Connect | ||||
|         channel.connect(clusterName); | ||||
| 
 | ||||
|         // Start state transfer | ||||
|         channel.getState(null, 0); | ||||
| 
 | ||||
|         // Do the things | ||||
|         processInput(); | ||||
| 
 | ||||
|         // Clean up | ||||
|         channel.close(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Quick and dirty implementaton of commons cli for command line args | ||||
|      * @param args the command line args | ||||
|      * @throws ParseException | ||||
|      */ | ||||
|     private void processCommandline(String[] args) throws ParseException { | ||||
| 
 | ||||
|         // Options, parser, friendly help | ||||
|         Options options = new Options(); | ||||
|         CommandLineParser parser = new DefaultParser(); | ||||
|         HelpFormatter formatter = new HelpFormatter(); | ||||
| 
 | ||||
|         options.addOption("u", "user", true, "User name") | ||||
|             .addOption("c", "cluster", true, "Cluster name"); | ||||
| 
 | ||||
|         CommandLine line = parser.parse(options, args); | ||||
| 
 | ||||
|         if (line.hasOption("user")) { | ||||
|             userName = line.getOptionValue("user"); | ||||
|         } else { | ||||
|             formatter.printHelp("JGroupsMessenger: need a user name.\n", options); | ||||
|             System.exit(-1); | ||||
|         } | ||||
| 
 | ||||
|         if (line.hasOption("cluster")) { | ||||
|             clusterName = line.getOptionValue("cluster"); | ||||
|         } else { | ||||
|             formatter.printHelp("JGroupsMessenger: need a cluster name.\n", options); | ||||
|             System.exit(-1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Start it up | ||||
|     public static void main(String[] args) throws Exception { | ||||
|         new JGroupsMessenger().start(args); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void viewAccepted(View newView) { | ||||
| 
 | ||||
|         // Save view if this is the first | ||||
|         if (lastView == null) { | ||||
|             System.out.println("Received initial view:"); | ||||
|             newView.forEach(System.out::println); | ||||
|         } else { | ||||
|             // Compare to last view | ||||
|             System.out.println("Received new view."); | ||||
| 
 | ||||
|             List<Address> newMembers = View.newMembers(lastView, newView); | ||||
|             System.out.println("New members: "); | ||||
|             newMembers.forEach(System.out::println); | ||||
| 
 | ||||
|             List<Address> exMembers = View.leftMembers(lastView, newView); | ||||
|             System.out.println("Exited members:"); | ||||
|             exMembers.forEach(System.out::println); | ||||
|         } | ||||
|         lastView = newView; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Loop on console input until we see 'x' to exit | ||||
|      */ | ||||
|     private void processInput() throws Exception { | ||||
| 
 | ||||
|         BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); | ||||
|         while (running) { | ||||
|             try { | ||||
| 
 | ||||
|                 // Get a destination, <enter> means broadcast | ||||
|                 Address destination = null; | ||||
|                 System.out.print("Enter a destination: "); | ||||
|                 System.out.flush(); | ||||
|                 String destinationName = in.readLine().toLowerCase(); | ||||
| 
 | ||||
|                 if (destinationName.equals("x")) { | ||||
|                     running = false; | ||||
|                     continue; | ||||
|                 } else if (!destinationName.isEmpty()) { | ||||
|                     destination = getAddress(destinationName) | ||||
|                       . orElseThrow(() -> new Exception("Destination not found")); | ||||
|                 } | ||||
| 
 | ||||
|                 // Accept a string to send | ||||
|                 System.out.print("Enter a message: "); | ||||
|                 System.out.flush(); | ||||
|                 String line = in.readLine().toLowerCase(); | ||||
|                 sendMessage(destination, line); | ||||
|             } catch (IOException ioe) { | ||||
|                 running = false; | ||||
|             } | ||||
|         } | ||||
|         System.out.println("Exiting."); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Send message from here | ||||
|      * @param destination the destination | ||||
|      * @param messageString the message | ||||
|      */ | ||||
|     private void sendMessage(Address destination, String messageString) { | ||||
|         try { | ||||
|             System.out.println("Sending " + messageString + " to " + destination); | ||||
|             Message message = new Message(destination, messageString); | ||||
|             channel.send(message); | ||||
|         } catch (Exception exception) { | ||||
|             System.err.println("Exception sending message: " + exception.getMessage()); | ||||
|             running = false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void receive(Message message) { | ||||
|         // Print source and dest with message | ||||
|         String line = "Message received from: " + message.getSrc() + " to: " + message.getDest() + " -> " + message.getObject(); | ||||
| 
 | ||||
|         // Only track the count of broadcast messages | ||||
|         // Tracking direct message would make for a pointless state | ||||
|         if (message.getDest() == null) { | ||||
|             messageCount++; | ||||
|             System.out.println("Message count: " + messageCount); | ||||
|         } | ||||
| 
 | ||||
|         System.out.println(line); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void getState(OutputStream output) throws Exception { | ||||
|         // Serialize into the stream | ||||
|         Util.objectToStream(messageCount, new DataOutputStream(output)); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setState(InputStream input) { | ||||
| 
 | ||||
|         // NOTE: since we know that incrementing the count and transferring the state | ||||
|         // is done inside the JChannel's thread, we don't have to worry about synchronizing | ||||
|         // messageCount. For production code it should be synchronized! | ||||
|         try { | ||||
|             // Deserialize | ||||
|             messageCount = Util.objectFromStream(new DataInputStream(input)); | ||||
|         } catch (Exception e) { | ||||
|             System.out.println("Error deserialing state!"); | ||||
|         } | ||||
|         System.out.println(messageCount + " is the current messagecount."); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private Optional<Address> getAddress(String name) { | ||||
|         View view = channel.view(); | ||||
|         return view.getMembers().stream().filter(address -> name.equals(address.toString())).findFirst(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										48
									
								
								jgroups/src/main/resources/udp.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								jgroups/src/main/resources/udp.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| <config xmlns="urn:org:jgroups" | ||||
|         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|         xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd"> | ||||
|     <UDP | ||||
|          mcast_port="${jgroups.udp.mcast_port:45588}" | ||||
|          ip_ttl="4" | ||||
|          tos="8" | ||||
|          ucast_recv_buf_size="5M" | ||||
|          ucast_send_buf_size="5M" | ||||
|          mcast_recv_buf_size="5M" | ||||
|          mcast_send_buf_size="5M" | ||||
|          max_bundle_size="64K" | ||||
|          enable_diagnostics="true" | ||||
|          thread_naming_pattern="cl" | ||||
| 
 | ||||
|          thread_pool.min_threads="0" | ||||
|          thread_pool.max_threads="20" | ||||
|          thread_pool.keep_alive_time="30000"/> | ||||
| 
 | ||||
|     <PING /> | ||||
|     <MERGE3 max_interval="30000" | ||||
|             min_interval="10000"/> | ||||
|     <FD_SOCK/> | ||||
|     <FD_ALL/> | ||||
|     <VERIFY_SUSPECT timeout="1500"  /> | ||||
|     <BARRIER /> | ||||
|     <pbcast.NAKACK2 xmit_interval="500" | ||||
|                     xmit_table_num_rows="100" | ||||
|                     xmit_table_msgs_per_row="2000" | ||||
|                     xmit_table_max_compaction_time="30000" | ||||
|                     use_mcast_xmit="false" | ||||
|                     discard_delivered_msgs="true"/> | ||||
|     <UNICAST3 xmit_interval="500" | ||||
|               xmit_table_num_rows="100" | ||||
|               xmit_table_msgs_per_row="2000" | ||||
|               xmit_table_max_compaction_time="60000" | ||||
|               conn_expiry_timeout="0"/> | ||||
|     <pbcast.STABLE desired_avg_gossip="50000" | ||||
|                    max_bytes="4M"/> | ||||
|     <pbcast.GMS print_local_addr="true" join_timeout="2000"/> | ||||
|     <UFC max_credits="2M" | ||||
|          min_threshold="0.4"/> | ||||
|     <MFC max_credits="2M" | ||||
|          min_threshold="0.4"/> | ||||
|     <FRAG2 frag_size="60K"  /> | ||||
|     <RSVP resend_interval="2000" timeout="10000"/> | ||||
|     <pbcast.STATE_TRANSFER /> | ||||
| </config> | ||||
| @ -31,6 +31,11 @@ | ||||
|             <version>${fastjson.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.json</groupId> | ||||
|             <artifactId>json</artifactId> | ||||
|             <version>20171018</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <properties> | ||||
|  | ||||
							
								
								
									
										59
									
								
								json/src/main/java/com/baeldung/jsonjava/CDLDemo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								json/src/main/java/com/baeldung/jsonjava/CDLDemo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import org.json.CDL; | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONTokener; | ||||
| 
 | ||||
| public class CDLDemo { | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("7.1. Producing JSONArray Directly from Comma Delimited Text: "); | ||||
|         jsonArrayFromCDT(); | ||||
|          | ||||
|         System.out.println("\n7.2. Producing Comma Delimited Text from JSONArray: "); | ||||
|         cDTfromJSONArray(); | ||||
|          | ||||
|         System.out.println("\n7.3.1. Producing JSONArray of JSONObjects Using Comma Delimited Text: "); | ||||
|         jaOfJOFromCDT2(); | ||||
|          | ||||
|         System.out.println("\n7.3.2. Producing JSONArray of JSONObjects Using Comma Delimited Text: "); | ||||
|         jaOfJOFromCDT2(); | ||||
|     } | ||||
|      | ||||
|     public static void jsonArrayFromCDT() { | ||||
|         JSONArray ja = CDL.rowToJSONArray(new JSONTokener("England, USA, Canada")); | ||||
|         System.out.println(ja); | ||||
|     } | ||||
|      | ||||
|     public static void cDTfromJSONArray() { | ||||
|         JSONArray ja = new JSONArray("[\"England\",\"USA\",\"Canada\"]"); | ||||
|         String cdt = CDL.rowToString(ja); | ||||
|         System.out.println(cdt); | ||||
|     } | ||||
|      | ||||
|     public static void jaOfJOFromCDT() { | ||||
|         String string =  | ||||
|           "name, city, age \n" + | ||||
|           "john, chicago, 22 \n" + | ||||
|           "gary, florida, 35 \n" + | ||||
|           "sal, vegas, 18"; | ||||
|           | ||||
|         JSONArray result = CDL.toJSONArray(string); | ||||
|         System.out.println(result.toString()); | ||||
|     } | ||||
|      | ||||
|     public static void jaOfJOFromCDT2() { | ||||
|         JSONArray ja = new JSONArray(); | ||||
|         ja.put("name"); | ||||
|         ja.put("city"); | ||||
|         ja.put("age"); | ||||
|           | ||||
|         String string =  | ||||
|           "john, chicago, 22 \n" + | ||||
|           "gary, florida, 35 \n" + | ||||
|           "sal, vegas, 18"; | ||||
|           | ||||
|         JSONArray result = CDL.toJSONArray(ja, string); | ||||
|         System.out.println(result.toString()); | ||||
|     } | ||||
|      | ||||
| } | ||||
							
								
								
									
										30
									
								
								json/src/main/java/com/baeldung/jsonjava/CookieDemo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								json/src/main/java/com/baeldung/jsonjava/CookieDemo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import org.json.Cookie; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| public class CookieDemo { | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("8.1. Converting a Cookie String into a JSONObject"); | ||||
|         cookieStringToJSONObject(); | ||||
|          | ||||
|         System.out.println("\n8.2. Converting a JSONObject into Cookie String"); | ||||
|         jSONObjectToCookieString(); | ||||
|     } | ||||
|      | ||||
|     public static void cookieStringToJSONObject() { | ||||
|         String cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/"; | ||||
|         JSONObject cookieJO = Cookie.toJSONObject(cookie); | ||||
|         System.out.println(cookieJO); | ||||
|     } | ||||
|      | ||||
|     public static void jSONObjectToCookieString() { | ||||
|         JSONObject cookieJO = new JSONObject(); | ||||
|         cookieJO.put("name", "username"); | ||||
|         cookieJO.put("value", "John Doe"); | ||||
|         cookieJO.put("expires", "Thu, 18 Dec 2013 12:00:00 UTC"); | ||||
|         cookieJO.put("path", "/"); | ||||
|         String cookie = Cookie.toString(cookieJO); | ||||
|         System.out.println(cookie); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								json/src/main/java/com/baeldung/jsonjava/DemoBean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								json/src/main/java/com/baeldung/jsonjava/DemoBean.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| public class DemoBean { | ||||
|     private int id; | ||||
|     private String name; | ||||
|     private boolean active; | ||||
|      | ||||
|     public int getId() { | ||||
|         return id; | ||||
|     } | ||||
|     public void setId(int id) { | ||||
|         this.id = id; | ||||
|     } | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
|     public boolean isActive() { | ||||
|         return active; | ||||
|     } | ||||
|     public void setActive(boolean active) { | ||||
|         this.active = active; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										27
									
								
								json/src/main/java/com/baeldung/jsonjava/HTTPDemo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								json/src/main/java/com/baeldung/jsonjava/HTTPDemo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import org.json.HTTP; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| public class HTTPDemo { | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("9.1. Converting JSONObject to HTTP Header: "); | ||||
|         jSONObjectToHTTPHeader(); | ||||
|          | ||||
|         System.out.println("\n9.2. Converting HTTP Header String Back to JSONObject: "); | ||||
|         hTTPHeaderToJSONObject(); | ||||
|     } | ||||
|      | ||||
|     public static void jSONObjectToHTTPHeader() { | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("Method", "POST"); | ||||
|         jo.put("Request-URI", "http://www.example.com/"); | ||||
|         jo.put("HTTP-Version", "HTTP/1.1"); | ||||
|         System.out.println(HTTP.toString(jo)); | ||||
|     } | ||||
|      | ||||
|     public static void hTTPHeaderToJSONObject() { | ||||
|         JSONObject obj = HTTP.toJSONObject("POST \"http://www.example.com/\" HTTP/1.1"); | ||||
|         System.out.println(obj); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								json/src/main/java/com/baeldung/jsonjava/JSONArrayDemo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								json/src/main/java/com/baeldung/jsonjava/JSONArrayDemo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| public class JSONArrayDemo { | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("5.1. Creating JSON Array: "); | ||||
|         creatingJSONArray(); | ||||
|          | ||||
|         System.out.println("\n5.2. Creating JSON Array from JSON string: "); | ||||
|         jsonArrayFromJSONString(); | ||||
|          | ||||
|         System.out.println("\n5.3. Creating JSON Array from Collection Object: "); | ||||
|         jsonArrayFromCollectionObj(); | ||||
|     } | ||||
|      | ||||
|     public static void creatingJSONArray() { | ||||
|         JSONArray ja = new JSONArray(); | ||||
|         ja.put(Boolean.TRUE); | ||||
|         ja.put("lorem ipsum"); | ||||
|           | ||||
|         // We can also put a JSONObject in JSONArray | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("name", "jon doe"); | ||||
|         jo.put("age", "22"); | ||||
|         jo.put("city", "chicago"); | ||||
|           | ||||
|         ja.put(jo); | ||||
|           | ||||
|         System.out.println(ja.toString()); | ||||
|     } | ||||
|      | ||||
|     public static void jsonArrayFromJSONString() { | ||||
|         JSONArray ja = new JSONArray("[true, \"lorem ipsum\", 215]"); | ||||
|         System.out.println(ja); | ||||
|     } | ||||
|      | ||||
|     public static void jsonArrayFromCollectionObj() { | ||||
|         List<String> list = new ArrayList<>(); | ||||
|         list.add("California"); | ||||
|         list.add("Texas"); | ||||
|         list.add("Hawaii"); | ||||
|         list.add("Alaska"); | ||||
|           | ||||
|         JSONArray ja = new JSONArray(list); | ||||
|         System.out.println(ja); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										59
									
								
								json/src/main/java/com/baeldung/jsonjava/JSONObjectDemo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								json/src/main/java/com/baeldung/jsonjava/JSONObjectDemo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| public class JSONObjectDemo { | ||||
|     public static void main(String[] args) { | ||||
|         System.out.println("4.1. Creating JSONObject: "); | ||||
|         jsonFromJSONObject(); | ||||
|          | ||||
|         System.out.println("\n4.2. Creating JSONObject from Map: "); | ||||
|         jsonFromMap(); | ||||
|          | ||||
|         System.out.println("\n4.3. Creating JSONObject from JSON string: "); | ||||
|         jsonFromJSONString(); | ||||
|          | ||||
|         System.out.println("\n4.4. Creating JSONObject from Java Bean: "); | ||||
|         jsonFromDemoBean(); | ||||
|     } | ||||
|      | ||||
|     public static void jsonFromJSONObject() { | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("name", "jon doe"); | ||||
|         jo.put("age", "22"); | ||||
|         jo.put("city", "chicago"); | ||||
|               | ||||
|         System.out.println(jo.toString()); | ||||
|     } | ||||
|      | ||||
|     public static void jsonFromMap() { | ||||
|         Map<String, String> map = new HashMap<>(); | ||||
|         map.put("name", "jon doe"); | ||||
|         map.put("age", "22"); | ||||
|         map.put("city", "chicago"); | ||||
|         JSONObject jo = new JSONObject(map); | ||||
|           | ||||
|         System.out.println(jo.toString()); | ||||
|     } | ||||
|      | ||||
|     public static void jsonFromJSONString() { | ||||
|         JSONObject jo = new JSONObject( | ||||
|           "{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}" | ||||
|         ); | ||||
|          | ||||
|         System.out.println(jo.toString()); | ||||
|     } | ||||
|      | ||||
|     public static void jsonFromDemoBean() { | ||||
|         DemoBean demo = new DemoBean(); | ||||
|         demo.setId(1); | ||||
|         demo.setName("lorem ipsum"); | ||||
|         demo.setActive(true); | ||||
|           | ||||
|         JSONObject jo = new JSONObject(demo); | ||||
|         System.out.println(jo); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,13 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import org.json.JSONTokener; | ||||
| 
 | ||||
| public class JSONTokenerDemo { | ||||
|     public static void main(String[] args) { | ||||
|         JSONTokener jt = new JSONTokener("Sample String"); | ||||
|           | ||||
|         while(jt.more()) { | ||||
|             System.out.println(jt.next()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,52 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import org.json.CDL; | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONTokener; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class CDLIntegrationTest { | ||||
|     @Test | ||||
|     public void givenCommaDelimitedText_thenConvertToJSONArray() { | ||||
|         JSONArray ja = CDL.rowToJSONArray(new JSONTokener("England, USA, Canada")); | ||||
|         assertEquals("[\"England\",\"USA\",\"Canada\"]", ja.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenJSONArray_thenConvertToCommaDelimitedText() { | ||||
|         JSONArray ja = new JSONArray("[\"England\",\"USA\",\"Canada\"]"); | ||||
|         String cdt = CDL.rowToString(ja); | ||||
|         assertEquals("England,USA,Canada", cdt.toString().trim()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenCommaDelimitedText_thenGetJSONArrayOfJSONObjects() { | ||||
|         String string =  | ||||
|           "name, city, age \n" + | ||||
|           "john, chicago, 22 \n" + | ||||
|           "gary, florida, 35 \n" + | ||||
|           "sal, vegas, 18"; | ||||
|           | ||||
|         JSONArray result = CDL.toJSONArray(string); | ||||
|         assertEquals("[{\"name\":\"john\",\"city\":\"chicago\",\"age\":\"22\"},{\"name\":\"gary\",\"city\":\"florida\",\"age\":\"35\"},{\"name\":\"sal\",\"city\":\"vegas\",\"age\":\"18\"}]", result.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenCommaDelimitedText_thenGetJSONArrayOfJSONObjects2() { | ||||
|         JSONArray ja = new JSONArray(); | ||||
|         ja.put("name"); | ||||
|         ja.put("city"); | ||||
|         ja.put("age"); | ||||
|           | ||||
|         String string =  | ||||
|           "john, chicago, 22 \n" + | ||||
|           "gary, florida, 35 \n" + | ||||
|           "sal, vegas, 18"; | ||||
|           | ||||
|         JSONArray result = CDL.toJSONArray(ja, string); | ||||
|         assertEquals("[{\"name\":\"john\",\"city\":\"chicago\",\"age\":\"22\"},{\"name\":\"gary\",\"city\":\"florida\",\"age\":\"35\"},{\"name\":\"sal\",\"city\":\"vegas\",\"age\":\"18\"}]", result.toString()); | ||||
|     } | ||||
|      | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import org.json.Cookie; | ||||
| import org.json.JSONObject; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class CookieIntegrationTest { | ||||
|     @Test | ||||
|     public void givenCookieString_thenConvertToJSONObject() { | ||||
|         String cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/"; | ||||
|         JSONObject cookieJO = Cookie.toJSONObject(cookie); | ||||
| 
 | ||||
|         assertEquals("{\"path\":\"/\",\"expires\":\"Thu, 18 Dec 2013 12:00:00 UTC\",\"name\":\"username\",\"value\":\"John Doe\"}", cookieJO.toString()); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenJSONObject_thenConvertToCookieString() { | ||||
|         JSONObject cookieJO = new JSONObject(); | ||||
|         cookieJO.put("name", "username"); | ||||
|         cookieJO.put("value", "John Doe"); | ||||
|         cookieJO.put("expires", "Thu, 18 Dec 2013 12:00:00 UTC"); | ||||
|         cookieJO.put("path", "/"); | ||||
|         String cookie = Cookie.toString(cookieJO); | ||||
| 
 | ||||
|         assertEquals("username=John Doe;expires=Thu, 18 Dec 2013 12:00:00 UTC;path=/", cookie.toString()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| import org.json.HTTP; | ||||
| import org.json.JSONObject; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class HTTPIntegrationTest { | ||||
|     @Test | ||||
|     public void givenJSONObject_thenConvertToHTTPHeader() { | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("Method", "POST"); | ||||
|         jo.put("Request-URI", "http://www.example.com/"); | ||||
|         jo.put("HTTP-Version", "HTTP/1.1"); | ||||
|          | ||||
|         assertEquals("POST \"http://www.example.com/\" HTTP/1.1"+HTTP.CRLF+HTTP.CRLF, HTTP.toString(jo)); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenHTTPHeader_thenConvertToJSONObject() { | ||||
|         JSONObject obj = HTTP.toJSONObject("POST \"http://www.example.com/\" HTTP/1.1"); | ||||
|          | ||||
|         assertEquals("{\"Request-URI\":\"http://www.example.com/\",\"Method\":\"POST\",\"HTTP-Version\":\"HTTP/1.1\"}", obj.toString()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,47 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONObject; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class JSONArrayIntegrationTest { | ||||
|     @Test | ||||
|     public void givenJSONJava_thenCreateNewJSONArrayFromScratch() { | ||||
|         JSONArray ja = new JSONArray(); | ||||
|         ja.put(Boolean.TRUE); | ||||
|         ja.put("lorem ipsum"); | ||||
|           | ||||
|         // We can also put a JSONObject in JSONArray | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("name", "jon doe"); | ||||
|         jo.put("age", "22"); | ||||
|         jo.put("city", "chicago"); | ||||
|           | ||||
|         ja.put(jo); | ||||
|           | ||||
|         assertEquals("[true,\"lorem ipsum\",{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}]", ja.toString()); | ||||
|     } | ||||
|      | ||||
|     @Test | ||||
|     public void givenJsonString_thenCreateNewJSONArray() { | ||||
|         JSONArray ja = new JSONArray("[true, \"lorem ipsum\", 215]"); | ||||
|         assertEquals("[true,\"lorem ipsum\",215]", ja.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenListObject_thenConvertItToJSONArray() { | ||||
|         List<String> list = new ArrayList<>(); | ||||
|         list.add("California"); | ||||
|         list.add("Texas"); | ||||
|         list.add("Hawaii"); | ||||
|         list.add("Alaska"); | ||||
|           | ||||
|         JSONArray ja = new JSONArray(list); | ||||
|         assertEquals("[\"California\",\"Texas\",\"Hawaii\",\"Alaska\"]", ja.toString()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,53 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import org.json.JSONObject; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class JSONObjectIntegrationTest { | ||||
|     @Test | ||||
|     public void givenJSONJava_thenCreateNewJSONObject() { | ||||
|         JSONObject jo = new JSONObject(); | ||||
|         jo.put("name", "jon doe"); | ||||
|         jo.put("age", "22"); | ||||
|         jo.put("city", "chicago"); | ||||
|               | ||||
|         assertEquals("{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}", jo.toString()); | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenMapObject_thenCreateJSONObject() { | ||||
|         Map<String, String> map = new HashMap<>(); | ||||
|         map.put("name", "jon doe"); | ||||
|         map.put("age", "22"); | ||||
|         map.put("city", "chicago"); | ||||
|         JSONObject jo = new JSONObject(map); | ||||
|           | ||||
|         assertEquals("{\"name\":\"jon doe\",\"city\":\"chicago\",\"age\":\"22\"}", jo.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenJsonString_thenCreateJSONObject() { | ||||
|         JSONObject jo = new JSONObject( | ||||
|           "{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}" | ||||
|         ); | ||||
|          | ||||
|         assertEquals("{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}", jo.toString()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenDemoBean_thenCreateJSONObject() { | ||||
|         DemoBean demo = new DemoBean(); | ||||
|         demo.setId(1); | ||||
|         demo.setName("lorem ipsum"); | ||||
|         demo.setActive(true); | ||||
|           | ||||
|         JSONObject jo = new JSONObject(demo); | ||||
|         assertEquals("{\"name\":\"lorem ipsum\",\"active\":true,\"id\":1}", jo.toString()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package com.baeldung.jsonjava; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| import org.json.JSONTokener; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class JSONTokenerIntegrationTest { | ||||
|     @Test | ||||
|     public void givenString_convertItToJSONTokens() { | ||||
|         String str = "Sample String"; | ||||
|         JSONTokener jt = new JSONTokener(str); | ||||
|          | ||||
|         char[] expectedTokens = str.toCharArray(); | ||||
|         int index = 0; | ||||
|          | ||||
|         while(jt.more()) { | ||||
|             assertEquals(expectedTokens[index++], jt.next()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -59,6 +59,7 @@ | ||||
| - [Intro to JDO Queries 2/2](http://www.baeldung.com/jdo-queries) | ||||
| - [Guide to google-http-client](http://www.baeldung.com/google-http-client) | ||||
| - [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) | ||||
| - [Programatically Create, Configure, and Run a Tomcat Server] (http://www.baeldung.com/tomcat-programmatic-setup) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -116,6 +116,12 @@ | ||||
|         </plugins> | ||||
|     </build> | ||||
|     <dependencies> | ||||
|     	<!-- https://mvnrepository.com/artifact/org.asynchttpclient/async-http-client --> | ||||
|         <dependency> | ||||
|             <groupId>org.asynchttpclient</groupId> | ||||
|             <artifactId>async-http-client</artifactId> | ||||
|             <version>${async.http.client.version}</version> | ||||
|         </dependency> | ||||
|         <!-- https://mvnrepository.com/artifact/org.beykery/neuroph/2.92 --> | ||||
|         <dependency> | ||||
|             <groupId>org.beykery</groupId> | ||||
| @ -710,6 +716,18 @@ | ||||
|             <classifier>test</classifier> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!-- tomcat --> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.tomcat</groupId> | ||||
|             <artifactId>tomcat-catalina</artifactId> | ||||
|             <version>${tomcat.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.milyn</groupId> | ||||
|             <artifactId>milyn-smooks-all</artifactId> | ||||
|             <version>${smooks.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|     <repositories> | ||||
|         <repository> | ||||
| @ -761,7 +779,7 @@ | ||||
|         <serenity.jira.version>1.1.3-rc.5</serenity.jira.version> | ||||
|         <serenity.plugin.version>1.4.0</serenity.plugin.version> | ||||
|         <jUnitParams.version>1.1.0</jUnitParams.version> | ||||
|         <netty.version>4.1.15.Final</netty.version> | ||||
|         <netty.version>4.1.20.Final</netty.version> | ||||
|         <commons.collections.version>4.1</commons.collections.version> | ||||
|         <junit.version>4.12</junit.version> | ||||
|         <java-lsh.version>0.10</java-lsh.version> | ||||
| @ -789,6 +807,9 @@ | ||||
|         <google-api.version>1.23.0</google-api.version> | ||||
|         <google-sheets.version>v4-rev493-1.21.0</google-sheets.version> | ||||
|         <kafka.version>1.0.0</kafka.version> | ||||
|         <smooks.version>1.7.0</smooks.version> | ||||
|         <docker.version>3.0.14</docker.version> | ||||
|         <tomcat.version>8.5.24</tomcat.version> | ||||
|         <async.http.client.version>2.2.0</async.http.client.version> | ||||
|     </properties> | ||||
| </project> | ||||
| @ -0,0 +1,45 @@ | ||||
| package com.baeldung.smooks.converter; | ||||
| 
 | ||||
| import com.baeldung.smooks.model.Order; | ||||
| import org.milyn.Smooks; | ||||
| import org.milyn.payload.JavaResult; | ||||
| import org.milyn.payload.StringResult; | ||||
| import org.xml.sax.SAXException; | ||||
| 
 | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class OrderConverter { | ||||
| 
 | ||||
|     public Order convertOrderXMLToOrderObject(String path) throws IOException, SAXException { | ||||
|         Smooks smooks = new Smooks(OrderConverter.class.getResourceAsStream("/smooks/smooks-mapping.xml")); | ||||
|         try { | ||||
|             JavaResult javaResult = new JavaResult(); | ||||
|             smooks.filterSource(new StreamSource(OrderConverter.class.getResourceAsStream(path)), javaResult); | ||||
|             return (Order) javaResult.getBean("order"); | ||||
|         } finally { | ||||
|             smooks.close(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public String convertOrderXMLtoEDIFACT(String path) throws IOException, SAXException { | ||||
|         return convertDocumentWithTempalte(path, "/smooks/smooks-transform-edi.xml"); | ||||
|     } | ||||
| 
 | ||||
|     public String convertOrderXMLtoEmailMessage(String path) throws IOException, SAXException { | ||||
|         return convertDocumentWithTempalte(path, "/smooks/smooks-transform-email.xml"); | ||||
|     } | ||||
| 
 | ||||
|     private String convertDocumentWithTempalte(String path, String config) throws IOException, SAXException { | ||||
|         Smooks smooks = new Smooks(config); | ||||
| 
 | ||||
|         try { | ||||
|             StringResult stringResult = new StringResult(); | ||||
|             smooks.filterSource(new StreamSource(OrderConverter.class.getResourceAsStream(path)), stringResult); | ||||
|             return stringResult.toString(); | ||||
|         } finally { | ||||
|             smooks.close(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,27 @@ | ||||
| package com.baeldung.smooks.converter; | ||||
| 
 | ||||
| import org.milyn.Smooks; | ||||
| import org.milyn.payload.JavaResult; | ||||
| import org.milyn.payload.StringResult; | ||||
| import org.milyn.validation.ValidationResult; | ||||
| import org.xml.sax.SAXException; | ||||
| 
 | ||||
| import javax.xml.transform.stream.StreamSource; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class OrderValidator { | ||||
| 
 | ||||
|     public ValidationResult validate(String path) throws IOException, SAXException { | ||||
|         Smooks smooks = new Smooks(OrderValidator.class.getResourceAsStream("/smooks/smooks-validation.xml")); | ||||
| 
 | ||||
|         try { | ||||
|             StringResult xmlResult = new StringResult(); | ||||
|             JavaResult javaResult = new JavaResult(); | ||||
|             ValidationResult validationResult = new ValidationResult(); | ||||
|             smooks.filterSource(new StreamSource(OrderValidator.class.getResourceAsStream(path)), xmlResult, javaResult, validationResult); | ||||
|             return validationResult; | ||||
|         } finally { | ||||
|             smooks.close(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										71
									
								
								libraries/src/main/java/com/baeldung/smooks/model/Item.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								libraries/src/main/java/com/baeldung/smooks/model/Item.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| package com.baeldung.smooks.model; | ||||
| 
 | ||||
| public class Item { | ||||
| 
 | ||||
|     public Item() { | ||||
|     } | ||||
| 
 | ||||
|     public Item(String code, Double price, Integer quantity) { | ||||
|         this.code = code; | ||||
|         this.price = price; | ||||
|         this.quantity = quantity; | ||||
|     } | ||||
| 
 | ||||
|     private String code; | ||||
|     private Double price; | ||||
|     private Integer quantity; | ||||
| 
 | ||||
| 
 | ||||
|     public String getCode() { | ||||
|         return code; | ||||
|     } | ||||
| 
 | ||||
|     public void setCode(String code) { | ||||
|         this.code = code; | ||||
|     } | ||||
| 
 | ||||
|     public Double getPrice() { | ||||
|         return price; | ||||
|     } | ||||
| 
 | ||||
|     public void setPrice(Double price) { | ||||
|         this.price = price; | ||||
|     } | ||||
| 
 | ||||
|     public Integer getQuantity() { | ||||
|         return quantity; | ||||
|     } | ||||
| 
 | ||||
|     public void setQuantity(Integer quantity) { | ||||
|         this.quantity = quantity; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) return true; | ||||
|         if (o == null || getClass() != o.getClass()) return false; | ||||
| 
 | ||||
|         Item item = (Item) o; | ||||
| 
 | ||||
|         if (code != null ? !code.equals(item.code) : item.code != null) return false; | ||||
|         if (price != null ? !price.equals(item.price) : item.price != null) return false; | ||||
|         return quantity != null ? quantity.equals(item.quantity) : item.quantity == null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         int result = code != null ? code.hashCode() : 0; | ||||
|         result = 31 * result + (price != null ? price.hashCode() : 0); | ||||
|         result = 31 * result + (quantity != null ? quantity.hashCode() : 0); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public String toString() { | ||||
|         return "Item{" + | ||||
|                 "code='" + code + '\'' + | ||||
|                 ", price=" + price + | ||||
|                 ", quantity=" + quantity + | ||||
|                 '}'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										52
									
								
								libraries/src/main/java/com/baeldung/smooks/model/Order.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								libraries/src/main/java/com/baeldung/smooks/model/Order.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| package com.baeldung.smooks.model; | ||||
| 
 | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class Order { | ||||
|     private Date creationDate; | ||||
|     private Long number; | ||||
|     private Status status; | ||||
|     private Supplier supplier; | ||||
|     private List<Item> items; | ||||
| 
 | ||||
|     public Date getCreationDate() { | ||||
|         return creationDate; | ||||
|     } | ||||
| 
 | ||||
|     public void setCreationDate(Date creationDate) { | ||||
|         this.creationDate = creationDate; | ||||
|     } | ||||
| 
 | ||||
|     public Long getNumber() { | ||||
|         return number; | ||||
|     } | ||||
| 
 | ||||
|     public void setNumber(Long number) { | ||||
|         this.number = number; | ||||
|     } | ||||
| 
 | ||||
|     public Status getStatus() { | ||||
|         return status; | ||||
|     } | ||||
| 
 | ||||
|     public void setStatus(Status status) { | ||||
|         this.status = status; | ||||
|     } | ||||
| 
 | ||||
|     public Supplier getSupplier() { | ||||
|         return supplier; | ||||
|     } | ||||
| 
 | ||||
|     public void setSupplier(Supplier supplier) { | ||||
|         this.supplier = supplier; | ||||
|     } | ||||
| 
 | ||||
|     public List<Item> getItems() { | ||||
|         return items; | ||||
|     } | ||||
| 
 | ||||
|     public void setItems(List<Item> items) { | ||||
|         this.items = items; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.baeldung.smooks.model; | ||||
| 
 | ||||
| public enum Status { | ||||
|     NEW, IN_PROGRESS, FINISHED | ||||
| } | ||||
| @ -0,0 +1,49 @@ | ||||
| package com.baeldung.smooks.model; | ||||
| 
 | ||||
| public class Supplier { | ||||
| 
 | ||||
|     private String name; | ||||
|     private String phoneNumber; | ||||
| 
 | ||||
|     public Supplier() { | ||||
|     } | ||||
| 
 | ||||
|     public Supplier(String name, String phoneNumber) { | ||||
|         this.name = name; | ||||
|         this.phoneNumber = phoneNumber; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public String getPhoneNumber() { | ||||
|         return phoneNumber; | ||||
|     } | ||||
| 
 | ||||
|     public void setPhoneNumber(String phoneNumber) { | ||||
|         this.phoneNumber = phoneNumber; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(Object o) { | ||||
|         if (this == o) return true; | ||||
|         if (o == null || getClass() != o.getClass()) return false; | ||||
| 
 | ||||
|         Supplier supplier = (Supplier) o; | ||||
| 
 | ||||
|         if (name != null ? !name.equals(supplier.name) : supplier.name != null) return false; | ||||
|         return phoneNumber != null ? phoneNumber.equals(supplier.phoneNumber) : supplier.phoneNumber == null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         int result = name != null ? name.hashCode() : 0; | ||||
|         result = 31 * result + (phoneNumber != null ? phoneNumber.hashCode() : 0); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								libraries/src/main/java/com/baeldung/tomcat/MyFilter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								libraries/src/main/java/com/baeldung/tomcat/MyFilter.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| package com.baeldung.tomcat; | ||||
| 
 | ||||
| import javax.servlet.*; | ||||
| import javax.servlet.annotation.WebFilter; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adi on 1/14/18. | ||||
|  */ | ||||
| @WebFilter(urlPatterns = "/my-servlet/*") | ||||
| public class MyFilter implements Filter { | ||||
| 
 | ||||
|     @Override | ||||
|     public void init(FilterConfig filterConfig) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | ||||
|         System.out.println("Filtering stuff..."); | ||||
|         HttpServletResponse httpResponse = (HttpServletResponse) response; | ||||
|         httpResponse.addHeader("myHeader", "myHeaderValue"); | ||||
|         chain.doFilter(request, httpResponse); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void destroy() { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								libraries/src/main/java/com/baeldung/tomcat/MyServlet.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								libraries/src/main/java/com/baeldung/tomcat/MyServlet.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| package com.baeldung.tomcat; | ||||
| 
 | ||||
| import javax.servlet.annotation.WebServlet; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adi on 1/10/18. | ||||
|  */ | ||||
| @WebServlet( | ||||
|   name = "com.baeldung.tomcat.programmatic.MyServlet", | ||||
|   urlPatterns = {"/my-servlet"} | ||||
| ) | ||||
| public class MyServlet extends HttpServlet { | ||||
| 
 | ||||
|     @Override | ||||
|     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { | ||||
|         resp.setStatus(HttpServletResponse.SC_OK); | ||||
|         resp.getWriter().write("test"); | ||||
|         resp.getWriter().flush(); | ||||
|         resp.getWriter().close(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,63 @@ | ||||
| package com.baeldung.tomcat; | ||||
| 
 | ||||
| import org.apache.catalina.Context; | ||||
| import org.apache.catalina.LifecycleException; | ||||
| import org.apache.catalina.startup.Tomcat; | ||||
| import org.apache.tomcat.util.descriptor.web.FilterDef; | ||||
| import org.apache.tomcat.util.descriptor.web.FilterMap; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| /** | ||||
|  * Created by adi on 1/10/18. | ||||
|  */ | ||||
| public class ProgrammaticTomcat { | ||||
| 
 | ||||
|     private Tomcat tomcat = null; | ||||
| 
 | ||||
|     //uncomment for live test | ||||
|     //    public static void main(String[] args) throws LifecycleException, ServletException, URISyntaxException, IOException { | ||||
|     //        startTomcat(); | ||||
|     //    } | ||||
| 
 | ||||
|     public void startTomcat() throws LifecycleException { | ||||
|         tomcat = new Tomcat(); | ||||
|         tomcat.setPort(8080); | ||||
|         tomcat.setHostname("localhost"); | ||||
|         String appBase = "."; | ||||
|         tomcat | ||||
|           .getHost() | ||||
|           .setAppBase(appBase); | ||||
| 
 | ||||
|         File docBase = new File(System.getProperty("java.io.tmpdir")); | ||||
|         Context context = tomcat.addContext("", docBase.getAbsolutePath()); | ||||
| 
 | ||||
|         //add a servlet | ||||
|         Class servletClass = MyServlet.class; | ||||
|         Tomcat.addServlet(context, servletClass.getSimpleName(), servletClass.getName()); | ||||
|         context.addServletMappingDecoded("/my-servlet/*", servletClass.getSimpleName()); | ||||
| 
 | ||||
|         //add a filter and filterMapping | ||||
|         Class filterClass = MyFilter.class; | ||||
|         FilterDef myFilterDef = new FilterDef(); | ||||
|         myFilterDef.setFilterClass(filterClass.getName()); | ||||
|         myFilterDef.setFilterName(filterClass.getSimpleName()); | ||||
|         context.addFilterDef(myFilterDef); | ||||
| 
 | ||||
|         FilterMap myFilterMap = new FilterMap(); | ||||
|         myFilterMap.setFilterName(filterClass.getSimpleName()); | ||||
|         myFilterMap.addURLPattern("/my-servlet/*"); | ||||
|         context.addFilterMap(myFilterMap); | ||||
| 
 | ||||
|         tomcat.start(); | ||||
|         //uncomment for live test | ||||
|         //        tomcat | ||||
|         //          .getServer() | ||||
|         //          .await(); | ||||
|     } | ||||
| 
 | ||||
|     public void stopTomcat() throws LifecycleException { | ||||
|         tomcat.stop(); | ||||
|         tomcat.destroy(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										8
									
								
								libraries/src/main/resources/smooks/email.ftl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								libraries/src/main/resources/smooks/email.ftl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| <#setting locale="en_US"> | ||||
| Hi, | ||||
| Order number #${order.number} created on ${order.creationDate?string["yyyy-MM-dd"]} is currently in ${order.status} status. | ||||
| Consider contact supplier "${supplier.name}"  with phone number: "${supplier.phoneNumber}". | ||||
| Order items: | ||||
| <#list items as item> | ||||
| ${item.quantity}  X ${item.code} (total price ${item.price * item.quantity}) | ||||
| </#list> | ||||
							
								
								
									
										1
									
								
								libraries/src/main/resources/smooks/item-rules.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								libraries/src/main/resources/smooks/item-rules.csv
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| "max_total","item.quantity * item.price < 300.00" | ||||
| 
 | 
							
								
								
									
										7
									
								
								libraries/src/main/resources/smooks/order.ftl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								libraries/src/main/resources/smooks/order.ftl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| <#setting locale="en_US"> | ||||
| UNA:+.? ' | ||||
| UNH+${order.number}+${order.status}+${order.creationDate?string["yyyy-MM-dd"]}' | ||||
| CTA+${supplier.name}+${supplier.phoneNumber}' | ||||
| <#list items as item> | ||||
| LIN+${item.quantity}+${item.code}+${item.price}' | ||||
| </#list> | ||||
							
								
								
									
										21
									
								
								libraries/src/main/resources/smooks/order.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								libraries/src/main/resources/smooks/order.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| { | ||||
|   "creationDate":"2018-01-14", | ||||
|   "orderNumber":771, | ||||
|   "orderStatus":"IN_PROGRESS", | ||||
|   "supplier":{ | ||||
|     "name":"CompanyX", | ||||
|     "phone":"1234567" | ||||
|   }, | ||||
|   "orderItems":[ | ||||
|     { | ||||
|       "quantity":1, | ||||
|       "code":"PX1234", | ||||
|       "price":9.99 | ||||
|     }, | ||||
|     { | ||||
|       "quantity":2, | ||||
|       "code":"RX1990", | ||||
|       "price":120.32 | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										20
									
								
								libraries/src/main/resources/smooks/order.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								libraries/src/main/resources/smooks/order.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| <order creation-date="2018-01-14"> | ||||
|     <order-number>771</order-number> | ||||
|     <order-status>IN_PROGRESS</order-status> | ||||
|     <supplier> | ||||
|         <name>CompanyX</name> | ||||
|         <phone>1234567</phone> | ||||
|     </supplier> | ||||
|     <order-items> | ||||
|         <item> | ||||
|             <quantity>1</quantity> | ||||
|             <code>PX1234</code> | ||||
|             <price>9.99</price> | ||||
|         </item> | ||||
|         <item> | ||||
|             <quantity>2</quantity> | ||||
|             <code>RX990</code> | ||||
|             <price>120.32</price> | ||||
|         </item> | ||||
|     </order-items> | ||||
| </order> | ||||
							
								
								
									
										29
									
								
								libraries/src/main/resources/smooks/smooks-mapping.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libraries/src/main/resources/smooks/smooks-mapping.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| <?xml version="1.0"?> | ||||
| <smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" | ||||
|                       xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd"> | ||||
| 
 | ||||
|     <jb:bean beanId="order" class="com.baeldung.smooks.model.Order" createOnElement="order"> | ||||
|         <jb:value property="number" data="order/order-number" /> | ||||
|         <jb:value property="status" data="order/order-status" /> | ||||
|         <jb:value property="creationDate" data="order/@creation-date"  decoder="Date"> | ||||
|             <jb:decodeParam name="format">yyyy-MM-dd</jb:decodeParam> | ||||
|         </jb:value> | ||||
|         <jb:wiring property="supplier" beanIdRef="supplier" /> | ||||
|         <jb:wiring property="items" beanIdRef="items" /> | ||||
|     </jb:bean> | ||||
| 
 | ||||
|     <jb:bean beanId="supplier" class="com.baeldung.smooks.model.Supplier" createOnElement="supplier"> | ||||
|         <jb:value property="name" data="name" /> | ||||
|         <jb:value property="phoneNumber" data="phone" /> | ||||
|     </jb:bean> | ||||
| 
 | ||||
|     <jb:bean beanId="items" class="java.util.ArrayList" createOnElement="order"> | ||||
|         <jb:wiring beanIdRef="item" /> | ||||
|     </jb:bean> | ||||
|     <jb:bean beanId="item" class="com.baeldung.smooks.model.Item" createOnElement="item"> | ||||
|         <jb:value property="code"  data="item/code" /> | ||||
|         <jb:value property="price" decoder="Double" data="item/price" /> | ||||
|         <jb:value property="quantity" decoder="Integer" data="item/quantity" /> | ||||
|     </jb:bean> | ||||
| 
 | ||||
| </smooks-resource-list> | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user