diff --git a/algorithms-modules/algorithms-miscellaneous-5/pom.xml b/algorithms-modules/algorithms-miscellaneous-5/pom.xml index c1739e3690..2d95bf2a01 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-5/pom.xml @@ -5,6 +5,18 @@ 4.0.0 algorithms-miscellaneous-5 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + algorithms-miscellaneous-5 diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java index ae434d88ad..5e4b35bfaf 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java @@ -1,15 +1,12 @@ package com.baeldung.algorithms.conversion; -import java.math.BigInteger; - - - +import com.google.common.io.BaseEncoding; +import jakarta.xml.bind.DatatypeConverter; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; -import com.google.common.io.BaseEncoding; - -import jakarta.xml.bind.DatatypeConverter; +import java.math.BigInteger; +import java.util.HexFormat; public class HexStringConverter { @@ -109,4 +106,14 @@ public class HexStringConverter { return BaseEncoding.base16() .decode(hexString.toUpperCase()); } + + public String encodeUsingHexFormat(byte[] bytes) { + HexFormat hexFormat = HexFormat.of(); + return hexFormat.formatHex(bytes); + } + + public byte[] decodeUsingHexFormat(String hexString) { + HexFormat hexFormat = HexFormat.of(); + return hexFormat.parseHex(hexString); + } } diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java index bb344e8b30..ee003ffac7 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java @@ -1,15 +1,13 @@ package com.baeldung.algorithms.conversion; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import org.apache.commons.codec.DecoderException; import org.hamcrest.text.IsEqualIgnoringCase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.baeldung.algorithms.conversion.HexStringConverter; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class ByteArrayConverterUnitTest { @@ -24,7 +22,7 @@ class ByteArrayConverterUnitTest { void shouldEncodeByteArrayToHexStringUsingBigIntegerToString() { byte[] bytes = getSampleBytes(); String hexString = getSampleHexString(); - if(hexString.charAt(0) == '0') { + if (hexString.charAt(0) == '0') { hexString = hexString.substring(1); } String output = hexStringConverter.encodeUsingBigIntegerToString(bytes); @@ -46,7 +44,7 @@ class ByteArrayConverterUnitTest { byte[] output = hexStringConverter.decodeUsingBigInteger(hexString); assertArrayEquals(bytes, output); } - + @Test void shouldEncodeByteArrayToHexStringUsingCharacterConversion() { byte[] bytes = getSampleBytes(); @@ -62,7 +60,7 @@ class ByteArrayConverterUnitTest { byte[] output = hexStringConverter.decodeHexString(hexString); assertArrayEquals(bytes, output); } - + @Test void shouldDecodeHexToByteWithInvalidHexCharacter() { assertThrows(IllegalArgumentException.class, () -> { @@ -118,12 +116,28 @@ class ByteArrayConverterUnitTest { assertArrayEquals(bytes, output); } + @Test + void shouldEncodeByteArrayToHexStringUsingHexFormat() throws DecoderException { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeUsingHexFormat(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + void shouldDecodeHexStringToByteArrayUsingHexFormat() throws DecoderException { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeUsingHexFormat(hexString); + assertArrayEquals(bytes, output); + } + private String getSampleHexString() { return "0af50c0e2d10"; } private byte[] getSampleBytes() { - return new byte[] { 10, -11, 12, 14, 45, 16 }; + return new byte[]{10, -11, 12, 14, 45, 16}; } } diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index a08948eda5..266d79cdfa 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -10,8 +10,4 @@ - [Check if Two Strings Are Rotations of Each Other](https://www.baeldung.com/java-string-check-strings-rotations) - [Find the Largest Prime Under the Given Number in Java](https://www.baeldung.com/java-largest-prime-lower-threshold) - [Count the Number of Unique Digits in an Integer using Java](https://www.baeldung.com/java-int-count-unique-digits) -- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence) -- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree) -- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test) -- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) diff --git a/algorithms-modules/algorithms-miscellaneous-7/pom.xml b/algorithms-modules/algorithms-miscellaneous-7/pom.xml index 3703ea5a16..c520eb6c25 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/pom.xml +++ b/algorithms-modules/algorithms-miscellaneous-7/pom.xml @@ -13,4 +13,22 @@ 1.0.0-SNAPSHOT + + 1.35 + + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumber.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumber.java new file mode 100644 index 0000000000..59b7e51a37 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumber.java @@ -0,0 +1,50 @@ +package com.baeldung.algorithms.perfectnumber; + +import java.util.stream.IntStream; + +class PerfectNumber { + + public static boolean isPerfectBruteForce(int number) { + int sum = 0; + for (int i = 1; i <= number / 2; i++) { + if (number % i == 0) { + sum += i; + } + } + return sum == number; + } + + public static boolean isPerfectStream(int number) { + int sum = IntStream.rangeClosed(2, (int) Math.sqrt(number)) + .filter(test -> number % test == 0) + .reduce(1, (s, test) -> s + test + (number / test)); + return sum == number; + } + + public static boolean isPerfectEuclidEuler(int number) { + int p = 2; + int perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1)); + while (perfectNumber <= number) { + if (perfectNumber == number) { + return true; + } + p++; + perfectNumber = (int) (Math.pow(2, p - 1) * (Math.pow(2, p) - 1)); + } + return false; + } + + public static boolean isPerfectEuclidEulerUsingShift(int number) { + int p = 2; + int perfectNumber = (2 << (p - 1)) * ((2 << p) - 1); + while (perfectNumber <= number) { + if (perfectNumber == number) { + return true; + } + p++; + perfectNumber = (2 << (p - 1)) * ((2 << p) - 1); + } + return false; + } + +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumberBenchmark.java b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumberBenchmark.java new file mode 100644 index 0000000000..9890c2887f --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/perfectnumber/PerfectNumberBenchmark.java @@ -0,0 +1,41 @@ +package com.baeldung.algorithms.perfectnumber; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@State(Scope.Benchmark) +public class PerfectNumberBenchmark { + + @Benchmark + public boolean bruteForceBenchmark() { + return PerfectNumber.isPerfectBruteForce(33550336); + } + + @Benchmark + public boolean streamBenchmark() { + return PerfectNumber.isPerfectStream(33550336); + } + + @Benchmark + public boolean euclidEulerBenchmark() { + return PerfectNumber.isPerfectEuclidEuler(33550336); + } + + @Benchmark + public boolean euclidEulerUsingShiftBenchmark() { + return PerfectNumber.isPerfectEuclidEulerUsingShift(33550336); + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(PerfectNumberBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(options).run(); + } +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/images/sampleImage.jpg b/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/images/sampleImage.jpg index c2f035ae64..5efe04c33a 100644 Binary files a/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/images/sampleImage.jpg and b/algorithms-modules/algorithms-miscellaneous-7/src/main/resources/images/sampleImage.jpg differ diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md deleted file mode 100644 index 55bc2abec5..0000000000 --- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md +++ /dev/null @@ -1,2 +0,0 @@ -## Relevant Articles -- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/perfectnumber/PerfectNumberUnitTest.java b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/perfectnumber/PerfectNumberUnitTest.java new file mode 100644 index 0000000000..e03e7c8653 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/perfectnumber/PerfectNumberUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.algorithms.perfectnumber; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PerfectNumberUnitTest { + @Test + void givenPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnTrue() { + assertTrue(PerfectNumber.isPerfectBruteForce(6)); + } + + @Test + void givenNonPerfectNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectBruteForce(10)); + } + + @Test + void givenNegativeNumber_whenCheckingIsPerfectBruteForce_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectBruteForce(-28)); + } + + @Test + void givenPerfectNumber_whenCheckingIsPerfectStream_thenReturnTrue() { + assertTrue(PerfectNumber.isPerfectStream(28)); + } + + @Test + void givenNonPerfectNumber_whenCheckingIsPerfectStream_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectStream(10)); + } + + @Test + void givenNegativeNumber_whenCheckingIsPerfectStream_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectStream(-6)); + } + + @Test + void givenPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnTrue() { + assertTrue(PerfectNumber.isPerfectEuclidEuler(28)); + } + + @Test + void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectEuclidEuler(10)); + } + + @Test + void givenNegativeNumber_whenCheckingIsPerfectEuclidEuler_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectEuclidEuler(-6)); + } + + @Test + void givenPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnTrue() { + assertTrue(PerfectNumber.isPerfectEuclidEulerUsingShift(28)); + } + + @Test + void givenNonPerfectNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(10)); + } + + @Test + void givenNegativeNumber_whenCheckingIsPerfectEuclidEulerUsingShift_thenReturnFalse() { + assertFalse(PerfectNumber.isPerfectEuclidEulerUsingShift(-6)); + } +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-8/README.md b/algorithms-modules/algorithms-miscellaneous-8/README.md new file mode 100644 index 0000000000..8bd185a7ba --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/README.md @@ -0,0 +1,9 @@ +### Relevant Articles: +- [Vigenère Cipher in Java](https://www.baeldung.com/java-vigenere-cipher) +- [Merge Overlapping Intervals in a Java Collection](https://www.baeldung.com/java-collection-merge-overlapping-intervals) +- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence) +- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree) +- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test) +- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits) +- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) +- More articles: [[<-- prev]](/algorithms-miscellaneous-7) \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java similarity index 98% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java index 79086fc61f..51e8350afc 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java @@ -1,6 +1,6 @@ package com.baeldung.algorithms.largestNumberRemovingK; -import java.util.*; +import java.util.Stack; public class LargestNumberRemoveKDigits { public static int findLargestNumberUsingArithmetic(int num, int k) { diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/Interval.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/Interval.java new file mode 100644 index 0000000000..f926d578be --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/Interval.java @@ -0,0 +1,37 @@ +package com.baeldung.algorithms.mergeintervals; + +import java.util.Objects; + +public class Interval { + int start; + int end; + + Interval(int start, int end) { + this.start = start; + this.end = end; + } + + public void setEnd(int end) { + this.end = end; + } + + @Override + public String toString() { + return "Interval{" + "start=" + start + ", end=" + end + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Interval interval = (Interval) o; + return start == interval.start && end == interval.end; + } + + @Override + public int hashCode() { + return Objects.hash(start, end); + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/MergeOverlappingIntervals.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/MergeOverlappingIntervals.java new file mode 100644 index 0000000000..ba424772d5 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/mergeintervals/MergeOverlappingIntervals.java @@ -0,0 +1,29 @@ +package com.baeldung.algorithms.mergeintervals; + +import java.util.ArrayList; +import java.util.List; + +public class MergeOverlappingIntervals { + + public List doMerge(List intervals) { + // Sort the intervals based on start time + intervals.sort((one, two) -> one.start - two.start); + + // Create somewhere to put the merged list, start it off with the earliest starting interval + ArrayList merged = new ArrayList<>(); + merged.add(intervals.get(0)); + + // Loop over each interval and merge if start time is before the end time of the + // previous interval + intervals.forEach(interval -> { + if (merged.get(merged.size() - 1).end > interval.start) { + merged.get(merged.size() - 1).setEnd(interval.end); + } else { + merged.add(interval); + } + }); + + return merged; + } + +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/Node.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/Node.java new file mode 100644 index 0000000000..52192415df --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/Node.java @@ -0,0 +1,11 @@ +package com.baeldung.algorithms.skiplist; + +class Node { + int value; + Node[] forward; // array to hold references to different levels + + public Node(int value, int level) { + this.value = value; + this.forward = new Node[level + 1]; // level + 1 because level is 0-based + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/SkipList.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/SkipList.java new file mode 100644 index 0000000000..53f7a3b0c8 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/skiplist/SkipList.java @@ -0,0 +1,92 @@ +package com.baeldung.algorithms.skiplist; + + +import java.util.Random; + +public class SkipList { + private Node head; + private int maxLevel; + private int level; + private Random random; + + public SkipList() { + maxLevel = 16; // maximum number of levels + level = 0; // current level of SkipList + head = new Node(Integer.MIN_VALUE, maxLevel); + random = new Random(); + } + + public void insert(int value) { + Node[] update = new Node[maxLevel + 1]; + Node current = this.head; + + for (int i = level; i >= 0; i--) { + while (current.forward[i] != null && current.forward[i].value < value) { + current = current.forward[i]; + } + update[i] = current; + } + + current = current.forward[0]; + + if (current == null || current.value != value) { + int lvl = randomLevel(); + + if (lvl > level) { + for (int i = level + 1; i <= lvl; i++) { + update[i] = head; + } + level = lvl; + } + + Node newNode = new Node(value, lvl); + for (int i = 0; i <= lvl; i++) { + newNode.forward[i] = update[i].forward[i]; + update[i].forward[i] = newNode; + } + } + } + + public boolean search(int value) { + Node current = this.head; + for (int i = level; i >= 0; i--) { + while (current.forward[i] != null && current.forward[i].value < value) { + current = current.forward[i]; + } + } + current = current.forward[0]; + return current != null && current.value == value; + } + + public void delete(int value) { + Node[] update = new Node[maxLevel + 1]; + Node current = this.head; + + for (int i = level; i >= 0; i--) { + while (current.forward[i] != null && current.forward[i].value < value) { + current = current.forward[i]; + } + update[i] = current; + } + current = current.forward[0]; + + if (current != null && current.value == value) { + for (int i = 0; i <= level; i++) { + if (update[i].forward[i] != current) break; + update[i].forward[i] = current.forward[i]; + } + + while (level > 0 && head.forward[level] == null) { + level--; + } + } + } + + private int randomLevel() { + int lvl = 0; + while (lvl < maxLevel && random.nextDouble() < 0.5) { + lvl++; + } + return lvl; + } +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java new file mode 100644 index 0000000000..2056688659 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java @@ -0,0 +1,82 @@ +package com.baeldung.algorithms.happynumber; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +class HappyNumberDecider { + + public static boolean isHappyNumber(int n) { + Set checkedNumbers = new HashSet<>(); + while (true) { + n = sumDigitsSquare(n); + if (n == 1) { + return true; + } + if (checkedNumbers.contains(n)) { + return false; + } + checkedNumbers.add(n); + } + } + + public static boolean isHappyNumberFloyd(int n) { + int slow = n; + int fast = n; + do { + slow = sumDigitsSquare(slow); + fast = sumDigitsSquare(sumDigitsSquare(fast)); + } while (slow != fast); + + return slow == 1; + } + + private static int sumDigitsSquare(int n) { + int squareSum = 0; + while (n != 0) { + squareSum += (n % 10) * (n % 10); + n /= 10; + } + return squareSum; + } +} + +public class HappyNumberUnitTest { + + @Test + void whenUsingIsHappyNumber_thenGetTheExpectedResult() { + assertTrue(HappyNumberDecider.isHappyNumber(7)); + assertTrue(HappyNumberDecider.isHappyNumber(10)); + assertTrue(HappyNumberDecider.isHappyNumber(13)); + assertTrue(HappyNumberDecider.isHappyNumber(19)); + assertTrue(HappyNumberDecider.isHappyNumber(23)); + + assertFalse(HappyNumberDecider.isHappyNumber(4)); + assertFalse(HappyNumberDecider.isHappyNumber(6)); + assertFalse(HappyNumberDecider.isHappyNumber(11)); + assertFalse(HappyNumberDecider.isHappyNumber(15)); + assertFalse(HappyNumberDecider.isHappyNumber(20)); + + } + + @Test + void whenUsingIsHappyNumber2_thenGetTheExpectedResult() { + assertTrue(HappyNumberDecider.isHappyNumberFloyd(7)); + assertTrue(HappyNumberDecider.isHappyNumberFloyd(10)); + assertTrue(HappyNumberDecider.isHappyNumberFloyd(13)); + assertTrue(HappyNumberDecider.isHappyNumberFloyd(19)); + assertTrue(HappyNumberDecider.isHappyNumberFloyd(23)); + + assertFalse(HappyNumberDecider.isHappyNumberFloyd(4)); + assertFalse(HappyNumberDecider.isHappyNumberFloyd(6)); + assertFalse(HappyNumberDecider.isHappyNumberFloyd(11)); + assertFalse(HappyNumberDecider.isHappyNumberFloyd(15)); + assertFalse(HappyNumberDecider.isHappyNumberFloyd(20)); + + } + +} \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/mergeintervals/MergeIntervalsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/mergeintervals/MergeIntervalsUnitTest.java new file mode 100644 index 0000000000..5f15fe00f6 --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/mergeintervals/MergeIntervalsUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.algorithms.mergeintervals; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +class MergeIntervalsUnitTest { + + private ArrayList intervals = new ArrayList<>(Arrays.asList( + new Interval(2, 5), + new Interval(13, 20), + new Interval(11, 15), + new Interval(1, 3) + )); + private ArrayList intervalsMerged = new ArrayList<>(Arrays.asList( + new Interval(1, 5), + new Interval(11, 20) + )); + + @Test + void givenIntervals_whenMerging_thenReturnMergedIntervals() { + MergeOverlappingIntervals merger = new MergeOverlappingIntervals(); + ArrayList result = (ArrayList) merger.doMerge(intervals); + assertArrayEquals(intervalsMerged.toArray(), result.toArray()); + } + +} diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java similarity index 94% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java index d3f0ec7997..ff31f99ed6 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java @@ -5,7 +5,9 @@ import org.junit.jupiter.api.Test; import java.util.NoSuchElementException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertNull; class BinaryTreeParentNodeFinderUnitTest { diff --git a/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/skiplist/SkipListUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/skiplist/SkipListUnitTest.java new file mode 100644 index 0000000000..6f8e5d042c --- /dev/null +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/skiplist/SkipListUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.algorithms.skiplist; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SkipListUnitTest { + + @Test + public void givenSkipList_WhenInsert_ThenSearchFound() { + SkipList skipList = new SkipList(); + + skipList.insert(3); + assertTrue(skipList.search(3), "Should find 3"); + + assertFalse(skipList.search(99), "Should not find 99"); + } + + @Test + public void givenSkipList_WhenDeleteElement_ThenRemoveFromList() { + SkipList skipList = new SkipList(); + + skipList.insert(3); + skipList.insert(7); + + skipList.delete(3); + assertFalse(skipList.search(3), "3 should have been deleted"); + + skipList.delete(99); + assertTrue(skipList.search(7), "7 should still exist"); + } + +} diff --git a/apache-libraries-2/README.md b/apache-libraries-2/README.md index 0933653be0..f7cdae70d7 100644 --- a/apache-libraries-2/README.md +++ b/apache-libraries-2/README.md @@ -1,5 +1,6 @@ ## Relevant Articles - [Understanding XSLT Processing in Java](https://www.baeldung.com/java-extensible-stylesheet-language-transformations) - [Add Camel Route at Runtime in Java](https://www.baeldung.com/java-camel-dynamic-route) - +- [Logging in Apache Camel](https://www.baeldung.com/java-apache-camel-logging) - More articles: [[<-- prev]](../apache-libraries) + diff --git a/apache-libraries-2/data/inbox/welcome.txt b/apache-libraries-2/data/inbox/welcome.txt new file mode 100644 index 0000000000..9f55d12685 --- /dev/null +++ b/apache-libraries-2/data/inbox/welcome.txt @@ -0,0 +1 @@ +Welcome to Baeldung \ No newline at end of file diff --git a/apache-libraries-2/data/json/name.json b/apache-libraries-2/data/json/name.json new file mode 100644 index 0000000000..1f7e064a56 --- /dev/null +++ b/apache-libraries-2/data/json/name.json @@ -0,0 +1,4 @@ +{ + "name" : "phillip", + "age" : 5 +} \ No newline at end of file diff --git a/apache-libraries-2/data/outbox/welcome.txt b/apache-libraries-2/data/outbox/welcome.txt new file mode 100644 index 0000000000..c4c82085cb --- /dev/null +++ b/apache-libraries-2/data/outbox/welcome.txt @@ -0,0 +1 @@ +WELCOME TO BAELDUNG \ No newline at end of file diff --git a/apache-libraries-2/data/output/name.json b/apache-libraries-2/data/output/name.json new file mode 100644 index 0000000000..d075754d1b --- /dev/null +++ b/apache-libraries-2/data/output/name.json @@ -0,0 +1 @@ +{"name":"phillip","age":5,"transformedName":"PHILLIP","transformedAge":15} \ No newline at end of file diff --git a/apache-libraries-2/pom.xml b/apache-libraries-2/pom.xml index 9b8d5d9ad4..b1e1a47d5f 100644 --- a/apache-libraries-2/pom.xml +++ b/apache-libraries-2/pom.xml @@ -35,11 +35,16 @@ camel-main ${camel.version} + + org.apache.camel + camel-jackson + ${camel.version} + 2.0.1.Final - 4.3.0 + 4.4.1 \ No newline at end of file diff --git a/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/CamelLoggingMainApp.java b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/CamelLoggingMainApp.java new file mode 100644 index 0000000000..8eaad95959 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/CamelLoggingMainApp.java @@ -0,0 +1,13 @@ +package com.baeldung.apachecamellogging; + +import org.apache.camel.main.Main; + +public class CamelLoggingMainApp { + + public static void main(String[] args) throws Exception { + Main main = new Main(); + main.configure() + .addRoutesBuilder(new FileCopierCamelRoute()); + main.run(args); + } +} diff --git a/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierCamelRoute.java b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierCamelRoute.java new file mode 100644 index 0000000000..cd09174d54 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierCamelRoute.java @@ -0,0 +1,25 @@ +package com.baeldung.apachecamellogging; + +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileCopierCamelRoute extends RouteBuilder { + + private static final Logger LOGGER = LoggerFactory.getLogger(FileCopierCamelRoute.class); + + public void configure() { + from("file:data/inbox?noop=true").log("We got an incoming file ${file:name} containing: ${body}") + .to("log:com.baeldung.apachecamellogging?level=INFO") + .process(process -> { + LOGGER.info("We are passing the message to a FileProcesor bean to capitalize the message body"); + }) + .bean(FileProcessor.class) + .to("file:data/outbox") + .to("log:com.baeldung.apachecamellogging?showBodyType=false&maxChars=20") + .log(LoggingLevel.DEBUG, "Output Process", "The Process ${id}") + .log("Successfully transfer file: ${file:name}"); + } +} \ No newline at end of file diff --git a/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierTracerCamelRoute.java b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierTracerCamelRoute.java new file mode 100644 index 0000000000..fea144ce66 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileCopierTracerCamelRoute.java @@ -0,0 +1,22 @@ +package com.baeldung.apachecamellogging; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.dataformat.JsonLibrary; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileCopierTracerCamelRoute extends RouteBuilder { + + Logger logger = LoggerFactory.getLogger(FileCopierTracerCamelRoute.class); + + public void configure() { + getContext().setTracing(true); + from("file:data/json?noop=true").to("log:input?level=INFO") + .unmarshal() + .json(JsonLibrary.Jackson) + .bean(FileProcessor.class, "transform") + .marshal() + .json(JsonLibrary.Jackson) + .to("file:data/output"); + } +} \ No newline at end of file diff --git a/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileProcessor.java b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileProcessor.java new file mode 100644 index 0000000000..478fb0ced0 --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/apachecamellogging/FileProcessor.java @@ -0,0 +1,23 @@ +package com.baeldung.apachecamellogging; + +import org.apache.camel.Body; + +import java.util.Map; + +public class FileProcessor { + + public String process(@Body String fileContent) { + String processedContent = fileContent.toUpperCase(); + return processedContent; + } + + public Map transform(Map input) { + String name = (String) input.get("name"); + int age = (int) input.get("age"); + + input.put("transformedName", name.toUpperCase()); + input.put("transformedAge", age + 10); + + return input; + } +} diff --git a/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java b/apache-libraries-2/src/test/java/com/baeldung/dynamicrouter/DynamicRouterRouteUnitTest.java similarity index 98% rename from apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java rename to apache-libraries-2/src/test/java/com/baeldung/dynamicrouter/DynamicRouterRouteUnitTest.java index 6401fa4be2..4b93d40dac 100644 --- a/apache-libraries-2/src/test/java/dynamicrouter/DynamicRouterRouteUnitTest.java +++ b/apache-libraries-2/src/test/java/com/baeldung/dynamicrouter/DynamicRouterRouteUnitTest.java @@ -1,4 +1,4 @@ -package dynamicrouter; +package com.baeldung.dynamicrouter; import com.baeldung.dynamicrouter.DynamicRouterRoute; import org.apache.camel.RoutesBuilder; diff --git a/apache-poi/pom.xml b/apache-poi/pom.xml index 876fca0efe..027ee06968 100644 --- a/apache-poi/pom.xml +++ b/apache-poi/pom.xml @@ -40,6 +40,16 @@ fastexcel-reader ${fastexcel.version} + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + @@ -64,6 +74,7 @@ 1.0.9 0.17.0 3.3.1 + 2.23.1 \ No newline at end of file diff --git a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml index acc14b55ff..2aa48a2f92 100644 --- a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml +++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml @@ -71,7 +71,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test @@ -112,7 +112,6 @@ 11.2 5.1.0 2.0.2 - 4.1.0 3.19.0 5.8.1 diff --git a/azure/pom.xml b/azure/pom.xml index 61ae0c7d68..52d7fa4864 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -98,7 +98,7 @@ spring.datasource.password - + test @@ -113,6 +113,14 @@ + + + + javax.xml.bind + jaxb-api + 2.4.0-b180830.0359 + + diff --git a/azure/src/main/java/com/baeldung/springboot/azure/User.java b/azure/src/main/java/com/baeldung/springboot/azure/User.java index d7a25aa246..1e7954d9b0 100644 --- a/azure/src/main/java/com/baeldung/springboot/azure/User.java +++ b/azure/src/main/java/com/baeldung/springboot/azure/User.java @@ -1,9 +1,9 @@ package com.baeldung.springboot.azure; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; /** * @author aiet diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java new file mode 100644 index 0000000000..f122b89f6e --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java @@ -0,0 +1,4 @@ +package com.baeldung; + +public class Unrelated { +} diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java index 9e6bd72680..8699e94b47 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java @@ -1,7 +1,7 @@ package com.baeldung; -import static org.junit.Assert.assertTrue; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; import java.util.Arrays; import java.util.Set; @@ -14,22 +14,22 @@ public class OuterUnitTest { @Test public void whenGetNestHostFromOuter_thenGetNestHost() { - is(Outer.class.getNestHost().getName()).equals(NEST_HOST_NAME); + assertEquals(NEST_HOST_NAME, Outer.class.getNestHost().getName()); } @Test public void whenGetNestHostFromInner_thenGetNestHost() { - is(Outer.Inner.class.getNestHost().getName()).equals(NEST_HOST_NAME); + assertEquals(NEST_HOST_NAME, Outer.Inner.class.getNestHost().getName()); } @Test public void whenCheckNestmatesForNestedClasses_thenGetTrue() { - is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(true); + assertTrue(Outer.Inner.class.isNestmateOf(Outer.class)); } @Test public void whenCheckNestmatesForUnrelatedClasses_thenGetFalse() { - is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(false); + assertFalse(Outer.Inner.class.isNestmateOf(Unrelated.class)); } @Test diff --git a/core-java-modules/core-java-18/README.md b/core-java-modules/core-java-18/README.md index 7616b84a57..21c57a3db9 100644 --- a/core-java-modules/core-java-18/README.md +++ b/core-java-modules/core-java-18/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Deprecate Finalization in Java 18](https://www.baeldung.com/java-18-deprecate-finalization) - [Simple Web Server in Java 18](https://www.baeldung.com/simple-web-server-java-18) +- [Internet Address Resolution SPI in Java](https://www.baeldung.com/java-service-provider-interface) diff --git a/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/InetAddressSPI.java b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/InetAddressSPI.java new file mode 100644 index 0000000000..0d5f5c486a --- /dev/null +++ b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/InetAddressSPI.java @@ -0,0 +1,44 @@ +package com.baeldung.inetspi; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.stream.Stream; + +import com.baeldung.inetspi.providers.CustomAddressResolverImpl; + +public class InetAddressSPI { + public String usingGetByName(String host) throws UnknownHostException { + InetAddress inetAddress = InetAddress.getByName(host); + return inetAddress.getHostAddress(); + } + + public String[] usingGetAllByName(String host) throws UnknownHostException { + InetAddress[] inetAddresses = InetAddress.getAllByName(host); + return Arrays.stream(inetAddresses).map(InetAddress::getHostAddress).toArray(String[]::new); + } + + public String usingGetByIp(byte[] ip) throws UnknownHostException { + InetAddress inetAddress = InetAddress.getByAddress(ip); + + return inetAddress.getHostName(); + } + + public String usingGetByIpAndReturnsCannonName(byte[] ip) throws UnknownHostException { + InetAddress inetAddress = InetAddress.getByAddress(ip); + + return inetAddress.getCanonicalHostName(); + } + + public String getHostUsingCustomImpl(byte[] ip) throws UnknownHostException { + + CustomAddressResolverImpl imp = new CustomAddressResolverImpl(); + return imp.get(null).lookupByAddress(ip); + } + + public Stream getIpUsingCustomImpl(String host) throws UnknownHostException { + + CustomAddressResolverImpl imp = new CustomAddressResolverImpl(); + return imp.get(null).lookupByName(host, null); + } +} diff --git a/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/Registry.java b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/Registry.java new file mode 100644 index 0000000000..db15f6a8d4 --- /dev/null +++ b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/Registry.java @@ -0,0 +1,56 @@ +package com.baeldung.inetspi; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Logger; +import java.util.stream.Stream; + +public class Registry { + private final Map> registry; + + private static final Logger LOGGER = Logger.getLogger(Registry.class.getName()); + + public Registry() { + registry = loadMapWithData(); + } + + public Stream getAddressesfromHost(String host) throws UnknownHostException { + LOGGER.info("Performing Forward Lookup for HOST : " + host); + if (!registry.containsKey(host)) { + throw new UnknownHostException("Missing Host information in Resolver"); + } + return registry.get(host) + .stream() + .map(add -> constructInetAddress(host, add)) + .filter(Objects::nonNull); + } + + public String getHostFromAddress(byte[] arr) throws UnknownHostException { + LOGGER.info("Performing Reverse Lookup for Address : " + Arrays.toString(arr)); + for (Map.Entry> entry : registry.entrySet()) { + if (entry.getValue() + .stream() + .anyMatch(ba -> Arrays.equals(ba, arr))) { + return entry.getKey(); + } + } + throw new UnknownHostException("Address Not Found"); + } + + private Map> loadMapWithData() { + return Map.of("baeldung-local.org", List.of(new byte[] { 1, 2, 3, 4 })); + } + + private static InetAddress constructInetAddress(String host, byte[] address) { + try { + return InetAddress.getByAddress(host, address); + } catch (UnknownHostException unknownHostException) { + return null; + } + } + +} diff --git a/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/providers/CustomAddressResolverImpl.java b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/providers/CustomAddressResolverImpl.java new file mode 100644 index 0000000000..0b1849c3f9 --- /dev/null +++ b/core-java-modules/core-java-18/src/main/java/com/baeldung/inetspi/providers/CustomAddressResolverImpl.java @@ -0,0 +1,42 @@ +package com.baeldung.inetspi.providers; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.net.spi.InetAddressResolver; +import java.net.spi.InetAddressResolverProvider; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import com.baeldung.inetspi.Registry; + +public class CustomAddressResolverImpl extends InetAddressResolverProvider { + + private static Logger LOGGER = Logger.getLogger(CustomAddressResolverImpl.class.getName()); + + private static Registry registry = new Registry(); + + @Override + public InetAddressResolver get(Configuration configuration) { + LOGGER.info("Using Custom Address Resolver :: " + this.name()); + LOGGER.info("Registry initialised"); + return new InetAddressResolver() { + @Override + public Stream lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException { + return registry.getAddressesfromHost(host); + } + + @Override + public String lookupByAddress(byte[] addr) throws UnknownHostException { + return registry.getHostFromAddress(addr); + } + }; + } + + @Override + public String name() { + return "CustomInternetAddressResolverImpl"; + } +} diff --git a/core-java-modules/core-java-18/src/test/java/com/baeldung/inetspi/InetAddressSPIUnitTest.java b/core-java-modules/core-java-18/src/test/java/com/baeldung/inetspi/InetAddressSPIUnitTest.java new file mode 100644 index 0000000000..ad8e6f0e54 --- /dev/null +++ b/core-java-modules/core-java-18/src/test/java/com/baeldung/inetspi/InetAddressSPIUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.inetspi; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +public class InetAddressSPIUnitTest { + @Test + public void givenInetAddress_whenUsingInetAddress_thenPerformResolution() throws UnknownHostException { + InetAddressSPI spi = new InetAddressSPI(); + Assert.assertNotNull(spi.usingGetByName("www.google.com")); + Assert.assertTrue(spi.usingGetAllByName("www.google.com").length > 1); + Assert.assertNotNull(spi.usingGetByIp(InetAddress.getByName("www.google.com") + .getAddress())); + Assert.assertNotNull(spi.usingGetByIpAndReturnsCannonName(InetAddress.getByName("www.google.com") + .getAddress())); + } + + @Test + public void givenCustomInetAddressImplementation_whenUsingInetAddress_thenPerformResolution() throws UnknownHostException { + InetAddressSPI spi = new InetAddressSPI(); + Assert.assertEquals("baeldung-local.org", spi.getHostUsingCustomImpl(new byte[] { 1, 2, 3, 4 })); + Stream response = spi.getIpUsingCustomImpl("baeldung-local.org"); + Assert.assertArrayEquals(new byte[] { 1, 2, 3, 4 }, response.findFirst() + .get() + .getAddress()); + } +} diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/PatternCaseLabels.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/PatternCaseLabels.java new file mode 100644 index 0000000000..7b64a382bc --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/PatternCaseLabels.java @@ -0,0 +1,32 @@ +package com.baeldung.java21; + +public class PatternCaseLabels { + + static String processInputOld(String input) { + String output; + switch (input) { + case null -> output = "Oops, null"; + case String s -> { + if ("Yes".equalsIgnoreCase(s)) { + output = "It's Yes"; + } else if ("No".equalsIgnoreCase(s)) { + output = "It's No"; + } else { + output = "Try Again"; + } + } + } + return output; + } + + static String processInputNew(String input) { + String output; + switch (input) { + case null -> output = "Oops, null"; + case String s when "Yes".equalsIgnoreCase(s) -> output = "It's Yes"; + case String s when "No".equalsIgnoreCase(s) -> output = "It's No"; + case String s -> output = "Try Again"; + } + return output; + } +} diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/RecordPattern.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/RecordPattern.java new file mode 100644 index 0000000000..e06539f888 --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/RecordPattern.java @@ -0,0 +1,36 @@ +package com.baeldung.java21; + +public class RecordPattern { + + record Point(int x, int y) {} + + public static int beforeRecordPattern(Object obj) { + int sum = 0; + if(obj instanceof Point p) { + int x = p.x(); + int y = p.y(); + sum = x+y; + } + return sum; + } + + public static int afterRecordPattern(Object obj) { + if(obj instanceof Point(int x, int y)) { + return x+y; + } + return 0; + } + + enum Color {RED, GREEN, BLUE} + + record ColoredPoint(Point point, Color color) {} + + record RandomPoint(ColoredPoint cp) {} + + public static Color getRamdomPointColor(RandomPoint r) { + if(r instanceof RandomPoint(ColoredPoint cp)) { + return cp.color(); + } + return null; + } +} diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/StringTemplates.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/StringTemplates.java new file mode 100644 index 0000000000..19dffd001b --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/StringTemplates.java @@ -0,0 +1,9 @@ +package com.baeldung.java21; + +public class StringTemplates { + + public String getStringTemplate() { + String name = "Baeldung"; + return STR."Welcome to \{name}"; + } +} diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/SwitchPattern.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/SwitchPattern.java new file mode 100644 index 0000000000..9ef7527415 --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/java21/SwitchPattern.java @@ -0,0 +1,56 @@ +package com.baeldung.java21; + +public class SwitchPattern { + + static class Account{ + double getBalance() { + return 0; + } + } + + static class SavingsAccount extends Account { + @Override + double getBalance() { + return 100; + } + } + + static class TermAccount extends Account { + @Override + double getBalance() { + return 1000; + } + } + static class CurrentAccount extends Account { + @Override + double getBalance() { + return 10000; + } + } + + static double getBalanceWithOutSwitchPattern(Account account) { + double balance = 0; + if(account instanceof SavingsAccount sa) { + balance = sa.getBalance(); + } + else if(account instanceof TermAccount ta) { + balance = ta.getBalance(); + } + else if(account instanceof CurrentAccount ca) { + balance = ca.getBalance(); + } + return balance; + } + + static double getBalanceWithSwitchPattern(Account account) { + double result; + switch (account) { + case null -> throw new IllegalArgumentException("Oops, account is null"); + case SavingsAccount sa -> result = sa.getBalance(); + case TermAccount ta -> result = ta.getBalance(); + case CurrentAccount ca -> result = ca.getBalance(); + default -> result = account.getBalance(); + } + return result; + } +} diff --git a/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/PatternCaseLabelsUnitTest.java b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/PatternCaseLabelsUnitTest.java new file mode 100644 index 0000000000..07b11ff50c --- /dev/null +++ b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/PatternCaseLabelsUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.java21; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +class PatternCaseLabelsUnitTest { + + @Test + void whenProcessInputOldWayWithYes_thenReturnOutput() { + assertEquals("It's Yes", PatternCaseLabels.processInputOld("Yes")); + } + + @Test + void whenProcessInputOldWayWithNo_thenReturnOutput() { + assertEquals("It's No", PatternCaseLabels.processInputOld("No")); + } + + @Test + void whenProcessInputOldWayWithNull_thenReturnOutput() { + assertEquals("Oops, null", PatternCaseLabels.processInputOld(null)); + } + + @Test + void whenProcessInputOldWayWithInvalidOption_thenReturnOutput() { + assertEquals("Try Again", PatternCaseLabels.processInputOld("Invalid Option")); + } + + @Test + void whenProcessInputNewWayWithYes_thenReturnOutput() { + assertEquals("It's Yes", PatternCaseLabels.processInputNew("Yes")); + } + + @Test + void whenProcessInputNewWayWithNo_thenReturnOutput() { + assertEquals("It's No", PatternCaseLabels.processInputNew("No")); + } + + @Test + void whenProcessInputNewWayWithNull_thenReturnOutput() { + assertEquals("Oops, null", PatternCaseLabels.processInputNew(null)); + } + + @Test + void whenProcessInputNewWayWithInvalidOption_thenReturnOutput() { + assertEquals("Try Again", PatternCaseLabels.processInputNew("Invalid Option")); + } + +} diff --git a/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/RecordPatternUnitTest.java b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/RecordPatternUnitTest.java new file mode 100644 index 0000000000..da8f4395e0 --- /dev/null +++ b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/RecordPatternUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.java21; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +import com.baeldung.java21.RecordPattern.Color; +import com.baeldung.java21.RecordPattern.ColoredPoint; +import com.baeldung.java21.RecordPattern.Point; +import com.baeldung.java21.RecordPattern.RandomPoint; + +class RecordPatternUnitTest { + + @Test + void whenNoRecordPattern_thenReturnOutput() { + assertEquals(5, RecordPattern.beforeRecordPattern(new Point(2, 3))); + } + + @Test + void whenRecordPattern_thenReturnOutput() { + assertEquals(5, RecordPattern.afterRecordPattern(new Point(2, 3))); + } + + @Test + void whenRecordPattern_thenReturnColorOutput() { + ColoredPoint coloredPoint = new ColoredPoint(new Point(2, 3), Color.GREEN); + RandomPoint randomPoint = new RandomPoint(coloredPoint); + assertEquals(Color.GREEN, RecordPattern.getRamdomPointColor(randomPoint)); + } +} diff --git a/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/StringTemplateUnitTest.java b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/StringTemplateUnitTest.java new file mode 100644 index 0000000000..340e9b54d9 --- /dev/null +++ b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/StringTemplateUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.java21; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +class StringTemplateUnitTest { + + @Test + void whenNoSwitchPattern_thenReturnSavingsAccountBalance() { + StringTemplates stringTemplates = new StringTemplates(); + assertEquals("Welcome to Baeldung", stringTemplates.getStringTemplate()); + } +} diff --git a/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/SwitchPatternUnitTest.java b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/SwitchPatternUnitTest.java new file mode 100644 index 0000000000..7429b303e9 --- /dev/null +++ b/core-java-modules/core-java-21/src/test/java/com/baeldung/java21/SwitchPatternUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.java21; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +class SwitchPatternUnitTest { + + @Test + void whenNoSwitchPattern_thenReturnSavingsAccountBalance() { + SwitchPattern.SavingsAccount savingsAccount = new SwitchPattern.SavingsAccount(); + assertEquals(100, SwitchPattern.getBalanceWithOutSwitchPattern(savingsAccount), 0); + } + + @Test + void whenSwitchPattern_thenReturnSavingsAccountBalance() { + SwitchPattern.SavingsAccount savingsAccount = new SwitchPattern.SavingsAccount(); + assertEquals(100, SwitchPattern.getBalanceWithSwitchPattern(savingsAccount), 0); + } +} diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 04461663e3..29ceaf29e1 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -9,9 +9,4 @@ - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) - [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time) -- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) -- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) -- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap) -- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of) -- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times) -- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) +- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) [[Next -->]](/core-java-modules/core-java-8-datetime-3) diff --git a/core-java-modules/core-java-8-datetime-3/README.md b/core-java-modules/core-java-8-datetime-3/README.md new file mode 100644 index 0000000000..d320466814 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-3/README.md @@ -0,0 +1,8 @@ +### Relevant Articles: + +- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) +- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) +- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap) +- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of) +- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times) +- [[<-- Prev]](/core-java-modules/core-java-8-datetime-2) diff --git a/core-java-modules/core-java-8-datetime-3/pom.xml b/core-java-modules/core-java-8-datetime-3/pom.xml new file mode 100644 index 0000000000..4e32190fcf --- /dev/null +++ b/core-java-modules/core-java-8-datetime-3/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + core-java-8-datetime-3 + jar + core-java-8-datetime-3 + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + joda-time + joda-time + ${joda-time.version} + + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + 1.8 + 1.8 + 2.12.5 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java index 9b898c87f5..9fbe4bc7fe 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java +++ b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java @@ -1,11 +1,11 @@ package com.baeldung.daterangeoverlap; -import java.time.LocalDate; -import java.util.Calendar; - import org.joda.time.DateTime; import org.joda.time.Interval; +import java.time.LocalDate; +import java.util.Calendar; + public class DateRangeOverlapChecker { public static boolean isOverlapUsingCalendarAndDuration(Calendar start1, Calendar end1, Calendar start2, Calendar end2) { diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java similarity index 92% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java index e09d823ce4..adf6c09107 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java +++ b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java @@ -1,20 +1,16 @@ package com.baeldung.localdatetoiso; +import org.apache.commons.lang3.time.FastDateFormat; +import org.joda.time.DateTimeZone; +import org.joda.time.format.ISODateTimeFormat; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Date; - -import org.apache.commons.lang3.time.DateFormatUtils; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.ISODateTimeFormat; - -import org.apache.commons.lang3.time.FastDateFormat; +import java.util.TimeZone; public class LocalDateToISO { public String formatUsingDateTimeFormatter(LocalDate localDate) { diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java similarity index 97% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java index 1ffddaa241..e2f526947e 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java @@ -1,45 +1,45 @@ -package com.baeldung.checkiftimebetweentwotimes; - -import org.junit.Test; - -import java.time.LocalTime; -import java.util.Calendar; -import java.util.Date; - -import static org.junit.Assert.assertTrue; - -public class CheckIfTimeBetweenTwoTimesUnitTest { - private LocalTime startTime = LocalTime.parse("09:00:00"); - private LocalTime endTime = LocalTime.parse("17:00:00"); - private LocalTime targetTime = LocalTime.parse("12:30:00"); - - @Test - public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() { - assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime)); - } - - @Test - public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() { - assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0); - } - - @Test - public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() { - Calendar startCalendar = Calendar.getInstance(); - startCalendar.set(Calendar.HOUR_OF_DAY, 9); - startCalendar.set(Calendar.MINUTE, 0); - Date startTime = startCalendar.getTime(); - - Calendar endCalendar = Calendar.getInstance(); - endCalendar.set(Calendar.HOUR_OF_DAY, 17); - endCalendar.set(Calendar.MINUTE, 0); - Date endTime = endCalendar.getTime(); - - Calendar targetCalendar = Calendar.getInstance(); - targetCalendar.set(Calendar.HOUR_OF_DAY, 12); - targetCalendar.set(Calendar.MINUTE, 30); - Date targetTime = targetCalendar.getTime(); - - assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime)); - } +package com.baeldung.checkiftimebetweentwotimes; + +import org.junit.Test; + +import java.time.LocalTime; +import java.util.Calendar; +import java.util.Date; + +import static org.junit.Assert.assertTrue; + +public class CheckIfTimeBetweenTwoTimesUnitTest { + private LocalTime startTime = LocalTime.parse("09:00:00"); + private LocalTime endTime = LocalTime.parse("17:00:00"); + private LocalTime targetTime = LocalTime.parse("12:30:00"); + + @Test + public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() { + assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime)); + } + + @Test + public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() { + assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0); + } + + @Test + public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() { + Calendar startCalendar = Calendar.getInstance(); + startCalendar.set(Calendar.HOUR_OF_DAY, 9); + startCalendar.set(Calendar.MINUTE, 0); + Date startTime = startCalendar.getTime(); + + Calendar endCalendar = Calendar.getInstance(); + endCalendar.set(Calendar.HOUR_OF_DAY, 17); + endCalendar.set(Calendar.MINUTE, 0); + Date endTime = endCalendar.getTime(); + + Calendar targetCalendar = Calendar.getInstance(); + targetCalendar.set(Calendar.HOUR_OF_DAY, 12); + targetCalendar.set(Calendar.MINUTE, 30); + Date targetTime = targetCalendar.getTime(); + + assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime)); + } } \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java index 5811cb6552..fa8145f71c 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java @@ -1,13 +1,13 @@ package com.baeldung.daterangeoverlap; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.joda.time.DateTime; +import org.junit.Test; import java.time.LocalDate; import java.util.Calendar; -import org.joda.time.DateTime; -import org.junit.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class DateRangeOverlapCheckerUnitTest { diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java similarity index 81% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java index 1979c91eca..c82cc2766d 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java @@ -1,13 +1,14 @@ package com.baeldung.localdatetoiso; +import org.junit.Test; + +import java.time.LocalDate; + import static org.junit.Assert.assertEquals; -import org.junit.Test; -import java.time.LocalDate; - public class LocalDateToISOUnitTest { @Test - void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){ + public void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){ LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); @@ -17,7 +18,7 @@ public class LocalDateToISOUnitTest { } @Test - void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){ + public void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){ LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); @@ -27,17 +28,18 @@ public class LocalDateToISOUnitTest { } @Test - void givenLocalDate_whenUsingJodaTime_thenISOFormat() { + public void givenLocalDate_whenUsingJodaTime_thenISOFormat() { LocalDateToISO localDateToISO = new LocalDateToISO(); org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 11, 6); String expected = "2023-11-06T00:00:00.000Z"; String actual = localDateToISO.formatUsingJodaTime(localDate); assertEquals(expected, actual); + assertEquals(expected, actual); } @Test - void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() { + public void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() { LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java similarity index 96% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java index 84f40c3cd5..298963fd70 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java @@ -1,25 +1,25 @@ -package com.baeldung.zoneoffsetandzoneidof; - -import org.junit.jupiter.api.Test; - -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ZoneOffSetAndZoneIdOfUnitTest { - - @Test - public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() { - OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC); - assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC); - } - - @Test - public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() { - ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")); - assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC")); - } -} +package com.baeldung.zoneoffsetandzoneidof; + +import org.junit.jupiter.api.Test; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ZoneOffSetAndZoneIdOfUnitTest { + + @Test + public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() { + OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC); + assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC); + } + + @Test + public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() { + ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")); + assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC")); + } +} diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 4f174b5163..e1ad221a31 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -9,9 +9,9 @@ - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) -- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort) - [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence) - [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators) - [PriorityQueue iterator() Method in Java](https://www.baeldung.com/java-priorityqueue-iterator) +- [Immutable vs Unmodifiable Collection in Java](https://www.baeldung.com/java-collection-immutable-unmodifiable-differences) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) diff --git a/core-java-modules/core-java-collections-5/pom.xml b/core-java-modules/core-java-collections-5/pom.xml index 939e479ba1..227b80ac4a 100644 --- a/core-java-modules/core-java-collections-5/pom.xml +++ b/core-java-modules/core-java-collections-5/pom.xml @@ -55,8 +55,8 @@ org.apache.maven.plugins maven-compiler-plugin - 9 - 9 + 16 + 16 diff --git a/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/immutables/ImmutableCollectionsUnitTest.java b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/immutables/ImmutableCollectionsUnitTest.java new file mode 100644 index 0000000000..6daec6d959 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/test/java/com/baeldung/immutables/ImmutableCollectionsUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.immutables; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +class ImmutableCollectionsUnitTest { + + @Test + void givenUnmodifiableMap_whenPutNewEntry_thenThrowsUnsupportedOperationException() { + Map modifiableMap = new HashMap<>(); + modifiableMap.put("name1", "Michael"); + modifiableMap.put("name2", "Harry"); + + Map unmodifiableMap = Collections.unmodifiableMap(modifiableMap); + + assertThrows(UnsupportedOperationException.class, () -> unmodifiableMap.put("name3", "Micky")); + } + + @Test + void givenUnmodifiableMap_whenPutNewEntryUsingOriginalReference_thenSuccess() { + Map modifiableMap = new HashMap<>(); + modifiableMap.put("name1", "Michael"); + modifiableMap.put("name2", "Harry"); + + Map unmodifiableMap = Collections.unmodifiableMap(modifiableMap); + modifiableMap.put("name3", "Micky"); + + assertEquals(modifiableMap, unmodifiableMap); + assertTrue(unmodifiableMap.containsKey("name3")); + } + + @Test + void givenImmutableMap_whenPutNewEntry_thenThrowsUnsupportedOperationException() { + Map immutableMap = Map.of("name1", "Michael", "name2", "Harry"); + + assertThrows(UnsupportedOperationException.class, () -> immutableMap.put("name3", "Micky")); + } + + @Test + void givenImmutableMap_whenUsecopyOf_thenExceptionOnPut() { + Map immutableMap = Map.of("name1", "Michael", "name2", "Harry"); + Map copyOfImmutableMap = Map.copyOf(immutableMap); + + assertThrows(UnsupportedOperationException.class, () -> copyOfImmutableMap.put("name3", "Micky")); + } +} + diff --git a/core-java-modules/core-java-collections-6/README.md b/core-java-modules/core-java-collections-6/README.md new file mode 100644 index 0000000000..736e91f110 --- /dev/null +++ b/core-java-modules/core-java-collections-6/README.md @@ -0,0 +1,7 @@ +========= + +## Core Java Collections Cookbooks and Examples + +### Relevant Articles: + +- More articles: [[<-- prev]](/core-java-modules/core-java-collections-5) diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml new file mode 100644 index 0000000000..3d38c3de35 --- /dev/null +++ b/core-java-modules/core-java-collections-6/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + core-java-collections-6 + jar + core-java-collections-6 + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.junit.platform + junit-platform-runner + ${junit-platform.version} + test + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + org.junit.vintage + junit-vintage-engine + ${junit.version} + test + + + org.roaringbitmap + RoaringBitmap + ${roaringbitmap.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + + + 5.9.2 + 0.9.38 + 1.36 + + + diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java new file mode 100644 index 0000000000..ca9390a3ee --- /dev/null +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.iteratorvsforeach; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class IteratorVsForeachUnitTest { + + private static Stream listProvider() { + return Stream.of(Arguments.of(List.of("String1", "String2", "unwanted"), List.of("String1", "String2"))); + } + + @Test + public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { + List names = Collections.emptyList(); + StringBuilder stringBuilder = new StringBuilder(); + names.forEach(stringBuilder::append); + assertEquals("", stringBuilder.toString()); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + // Separate collection for items to be removed + List toRemove = new ArrayList<>(); + + // Using forEach to identify items to remove + input.forEach(item -> { + if (item.equals("unwanted")) { + toRemove.add(item); + } + }); + + // Removing the identified items from the original list + mutableList.removeAll(toRemove); + assertIterableEquals(expected, mutableList); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + Iterator it = mutableList.iterator(); + while (it.hasNext()) { + String item = it.next(); + if (item.equals("unwanted")) { + it.remove(); // Safely remove item + } + } + assertIterableEquals(expected, mutableList); + } + +} diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java new file mode 100644 index 0000000000..2f1b2cc083 --- /dev/null +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.listiteration; + +import org.junit.jupiter.api.Test; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +public class ListIterationUnitTest { + + List programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++")); + List numbers = new ArrayList<>(List.of(1, 2, 3)); + + @Test + public void givenStringList_whenAddElementWithListIterator_thenModifiedList() { + ListIterator listIterator = programmingLanguages.listIterator(); + while (listIterator.hasNext()) { + String language = listIterator.next(); + if (language.equals("Python")) { + listIterator.add("JavaScript"); + } + } + + assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() { + ListIterator listIterator = numbers.listIterator(); + while (listIterator.hasNext()) { + int num = listIterator.next(); + if (num == 2) { + listIterator.add(num * 10); + } + } + assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers); + } + + @Test + public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() { + List copyOfWords = new ArrayList<>(programmingLanguages); + for (String word : copyOfWords) { + programmingLanguages.add(word.toUpperCase()); // Modified: Convert to uppercase + } + assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyElementWithEnhancedForLoopAndCopy_thenModifiedList() { + List copyOfNumbers = new ArrayList<>(numbers); + for (int num : copyOfNumbers) { + numbers.add(num * 2); + } + assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers); + } + + @Test + public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() { + programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList()); + assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() { + numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList()); + assertIterableEquals(Arrays.asList(3, 6, 9), numbers); + } + +} diff --git a/core-java-modules/core-java-collections-conversions-3/README.md b/core-java-modules/core-java-collections-conversions-3/README.md index 959e4e8160..96727e8d88 100644 --- a/core-java-modules/core-java-collections-conversions-3/README.md +++ b/core-java-modules/core-java-collections-conversions-3/README.md @@ -5,3 +5,4 @@ This module contains articles about conversions among Collection types in Java. ### Relevant Articles: - [Converting HashMap Values to an ArrayList in Java](https://www.baeldung.com/java-hashmap-arraylist) - [Joining a List in Java With Commas and “and”](https://www.baeldung.com/java-string-concatenation-natural-language) +- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) diff --git a/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java b/core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java rename to core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java deleted file mode 100644 index 25f39e9a13..0000000000 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.baeldung.java.listInitialization; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import lombok.extern.java.Log; - -import org.junit.Assert; -import org.junit.Test; - -@Log -public class ListInitializationUnitTest { - - @Test - public void givenAnonymousInnerClass_thenInitialiseList() { - List cities = new ArrayList() { - { - add("New York"); - add("Rio"); - add("Tokyo"); - } - }; - - Assert.assertTrue(cities.contains("New York")); - } - - @Test - public void givenArraysAsList_thenInitialiseList() { - List list = Arrays.asList("foo", "bar"); - - Assert.assertTrue(list.contains("foo")); - } - - @Test(expected = UnsupportedOperationException.class) - public void givenArraysAsList_whenAdd_thenUnsupportedException() { - List list = Arrays.asList("foo", "bar"); - - list.add("baz"); - } - - @Test - public void givenArraysAsList_whenCreated_thenShareReference() { - String[] array = { "foo", "bar" }; - List list = Arrays.asList(array); - array[0] = "baz"; - Assert.assertEquals("baz", list.get(0)); - } - - @Test - public void givenStream_thenInitializeList() { - List list = Stream.of("foo", "bar") - .collect(Collectors.toList()); - - Assert.assertTrue(list.contains("foo")); - } -} diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java new file mode 100644 index 0000000000..4b06621fef --- /dev/null +++ b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.java.listinitialization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; + +import lombok.extern.java.Log; + +@Log +public class ListInitializationUnitTest { + + @Test + public void givenAnonymousInnerClass_thenInitialiseList() { + List cities = new ArrayList() { + { + add("New York"); + add("Rio"); + add("Tokyo"); + } + }; + + assertTrue(cities.contains("New York")); + } + + @Test + public void givenArraysAsList_thenInitialiseList() { + List list = Arrays.asList("foo", "bar"); + + assertTrue(list.contains("foo")); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenArraysAsList_whenAdd_thenUnsupportedException() { + List list = Arrays.asList("foo", "bar"); + + list.add("baz"); + } + + @Test + public void givenArraysAsList_whenUsingArrayListConstructor_thenWeCanAddOrRemove() { + List list = new ArrayList<>(Arrays.asList("foo", "bar")); + + list.add("baz"); + assertEquals(List.of("foo", "bar","baz"), list); + + list.remove("baz"); + assertEquals(List.of("foo", "bar"), list); + } + + @Test + public void givenArraysAsList_whenCreated_thenShareReference() { + String[] array = { "foo", "bar" }; + List list = Arrays.asList(array); + array[0] = "baz"; + assertEquals("baz", list.get(0)); + } + + @Test + public void givenIntNumbers_whenRequiredLong_thenCastAutomatically() { + int intNum = 42; + long longNum = intNum; + + assertEquals(42L, longNum); + } + + @Test + public void givenArrayAsList_whenRequiredLongList_thenGetExpectedResult() { + List listOfLongFixedSize = Arrays.asList(1L, 2L, 3L); + List listOfLong = new ArrayList<>(Arrays.asList(1L, 2L, 3L)); + + List expected = List.of(1L, 2L, 3L); + + assertEquals(expected, listOfLongFixedSize); + assertEquals(expected, listOfLong); + } + + @Test + public void givenStream_thenInitializeList() { + List list = Stream.of("foo", "bar") + .collect(Collectors.toList()); + + assertTrue(list.contains("foo")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-6/README.md b/core-java-modules/core-java-collections-list-6/README.md index 8a8ed181c6..c66a611caf 100644 --- a/core-java-modules/core-java-collections-list-6/README.md +++ b/core-java-modules/core-java-collections-list-6/README.md @@ -5,3 +5,4 @@ - [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another) - [Reset ListIterator to First Element of the List in Java](https://www.baeldung.com/java-reset-listiterator) - [Modify and Print List Items With Java Streams](https://www.baeldung.com/java-stream-list-update-print-elements) +- [Add One Element to an Immutable List in Java](https://www.baeldung.com/java-immutable-list-add-element) diff --git a/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/addtoimmutablelist/AddElementsToImmutableListUnitTest.java b/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/addtoimmutablelist/AddElementsToImmutableListUnitTest.java new file mode 100644 index 0000000000..397aca8906 --- /dev/null +++ b/core-java-modules/core-java-collections-list-6/src/test/java/com/baeldung/addtoimmutablelist/AddElementsToImmutableListUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.addtoimmutablelist; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class AddElementsToImmutableListUnitTest { + + public static List appendAnElement(List immutableList, T element) { + List tmpList = new ArrayList<>(immutableList); + tmpList.add(element); + return Collections.unmodifiableList(tmpList); + } + + @SafeVarargs + public static List appendElements(List immutableList, T... elements) { + List tmpList = new ArrayList<>(immutableList); + tmpList.addAll(Arrays.asList(elements)); + return Collections.unmodifiableList(tmpList); + } + + @Test + void whenCallingAppendAnElement_thenGetExpectedResult() { + List myList = List.of("A", "B", "C", "D", "E"); + List expected = List.of("A", "B", "C", "D", "E", "F"); + List result = appendAnElement(myList, "F"); + assertThat(result).isEqualTo(expected) + .isUnmodifiable(); + } + + @Test + void whenCallingAppendElements_thenGetExpectedResult() { + List myList = List.of("A", "B", "C", "D", "E"); + List expected1 = List.of("A", "B", "C", "D", "E", "F"); + List result1 = appendElements(myList, "F"); + assertThat(result1).isEqualTo(expected1) + .isUnmodifiable(); + + List expected2 = List.of("A", "B", "C", "D", "E", "F", "G", "H", "I"); + List result2 = appendElements(myList, "F", "G", "H", "I"); + assertThat(result2).isEqualTo(expected2) + .isUnmodifiable(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-8/README.md b/core-java-modules/core-java-collections-maps-8/README.md new file mode 100644 index 0000000000..f3dcc6b8bb --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Find Map Keys with Duplicate Values in Java](https://www.baeldung.com/java-map-find-keys-repeated-values) diff --git a/core-java-modules/core-java-collections-maps-8/pom.xml b/core-java-modules/core-java-collections-maps-8/pom.xml new file mode 100644 index 0000000000..8c4454cf0f --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + core-java-collections-maps-8 + core-java-collections-maps-8 + jar + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.util=ALL-UNNAMED + + + + + + diff --git a/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/valuetokeyset/ConvertMapKeyValueToMapValueKeySetUnitTest.java b/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/valuetokeyset/ConvertMapKeyValueToMapValueKeySetUnitTest.java new file mode 100644 index 0000000000..a7491fd257 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/valuetokeyset/ConvertMapKeyValueToMapValueKeySetUnitTest.java @@ -0,0 +1,127 @@ +package com.baeldung.map.valuetokeyset; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.toSet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; + +public class ConvertMapKeyValueToMapValueKeySetUnitTest { + + private static final Map INPUT_MAP = Map.of( + // @formatter:off + "Kai", "Linux", + "Eric", "MacOS", + "Kevin", "Windows", + "Liam", "MacOS", + "David", "Linux", + "Saajan", "Windows", + "Loredana", "MacOS" + // @formatter:on + ); + + private static final Map> EXPECTED = Map.of( + // @formatter:off + "Linux", Set.of("Kai", "David"), + "Windows", Set.of("Saajan", "Kevin"), + "MacOS", Set.of("Eric", "Liam", "Loredana") + // @formatter:on + ); + + private static final Map INPUT_MAP_WITH_NULLS = new HashMap(INPUT_MAP) {{ + put("Tom", null); + put("Jerry", null); + put(null, null); + }}; + + private static final Map> EXPECTED_WITH_NULLS = new HashMap>(EXPECTED) {{ + put(null, new HashSet() {{ + add("Tom"); + add("Jerry"); + add(null); + }}); + }}; + + public static Map> transformMap(Map input) { + Map> resultMap = new HashMap<>(); + for (Map.Entry entry : input.entrySet()) { + if (!resultMap.containsKey(entry.getValue())) { + resultMap.put(entry.getValue(), new HashSet<>()); + } + resultMap.get(entry.getValue()) + .add(entry.getKey()); + } + return resultMap; + } + + @Test + void whenUsingClassicLoopBasedSolution_thenGetExpectedResult() { + Map> result = transformMap(INPUT_MAP); + assertEquals(EXPECTED, result); + + Map> result2 = transformMap(INPUT_MAP_WITH_NULLS); + assertEquals(EXPECTED_WITH_NULLS, result2); + } + + @Test + void whenUsingJava8StreamGroupingBy_thenGetExpectedResult() { + Map> result = INPUT_MAP.entrySet() + .stream() + .collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toSet()))); + assertEquals(EXPECTED, result); + + assertThrows(NullPointerException.class, () -> INPUT_MAP_WITH_NULLS.entrySet() + .stream() + .collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toSet())))); + } + + @Test + void whenUsingJava8ForEach_thenGetExpectedResult() { + Map> result = new HashMap<>(); + INPUT_MAP.forEach((key, value) -> result.computeIfAbsent(value, k -> new HashSet<>()) + .add(key)); + assertEquals(EXPECTED, result); + + Map> result2 = new HashMap<>(); + INPUT_MAP_WITH_NULLS.forEach((key, value) -> result2.computeIfAbsent(value, k -> new HashSet<>()) + .add(key)); + assertEquals(EXPECTED_WITH_NULLS, result2); + } + + @Test + void whenUsingGuavaMultiMapCollector_thenGetExpectedResult() { + Map> result = INPUT_MAP.entrySet() + .stream() + .collect(collectingAndThen(Multimaps.toMultimap(Map.Entry::getValue, Map.Entry::getKey, HashMultimap::create), Multimaps::asMap)); + assertEquals(EXPECTED, result); + + Map> result2 = INPUT_MAP_WITH_NULLS.entrySet() + .stream() + .collect(collectingAndThen(Multimaps.toMultimap(Map.Entry::getValue, Map.Entry::getKey, HashMultimap::create), Multimaps::asMap)); + assertEquals(EXPECTED_WITH_NULLS, result2); + } + + @Test + void whenUsingGuavaInvertFromAndForMap_thenGetExpectedResult() { + SetMultimap multiMap = Multimaps.invertFrom(Multimaps.forMap(INPUT_MAP), HashMultimap.create()); + Map> result = Multimaps.asMap(multiMap); + assertEquals(EXPECTED, result); + + SetMultimap multiMapWithNulls = Multimaps.invertFrom(Multimaps.forMap(INPUT_MAP_WITH_NULLS), HashMultimap.create()); + Map> result2 = Multimaps.asMap(multiMapWithNulls); + assertEquals(EXPECTED_WITH_NULLS, result2); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-set-2/README.md b/core-java-modules/core-java-collections-set-2/README.md index ee41908faf..1eed623824 100644 --- a/core-java-modules/core-java-collections-set-2/README.md +++ b/core-java-modules/core-java-collections-set-2/README.md @@ -6,4 +6,5 @@ - [How to Get First Item From a Java Set](https://www.baeldung.com/first-item-set) - [Cartesian Product of Any Number of Sets in Java](https://www.baeldung.com/java-cartesian-product-sets) - [How to Get Index of an Item in Java Set](https://www.baeldung.com/java-set-element-find-index) +- [Check if an Element Is Present in a Set in Java](https://www.baeldung.com/java-set-membership) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-set) diff --git a/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/checkifpresentinset/CheckIfPresentInSetUnitTest.java b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/checkifpresentinset/CheckIfPresentInSetUnitTest.java new file mode 100644 index 0000000000..9d3c9a5c0d --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/checkifpresentinset/CheckIfPresentInSetUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.checkifpresentinset; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.SetUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class CheckIfPresentInSetUnitTest { + + private static final Set CITIES = new HashSet<>(); + + @BeforeAll + static void setup() { + CITIES.add("Paris"); + CITIES.add("London"); + CITIES.add("Tokyo"); + CITIES.add("Tamassint"); + CITIES.add("New york"); + } + + @Test + void givenASet_whenUsingStreamAnyMatchMethod_thenCheck() { + boolean isPresent = CITIES.stream() + .anyMatch(city -> city.equals("London")); + + assertThat(isPresent).isTrue(); + } + + @Test + void givenASet_whenUsingStreamFilterMethod_thenCheck() { + long resultCount = CITIES.stream() + .filter(city -> city.equals("Tamassint")) + .count(); + + assertThat(resultCount).isPositive(); + } + + @Test + void givenASet_whenUsingContainsMethod_thenCheck() { + assertThat(CITIES.contains("London")).isTrue(); + assertThat(CITIES.contains("Madrid")).isFalse(); + } + + @Test + void givenASet_whenUsingCollectionsDisjointMethod_thenCheck() { + boolean isPresent = !Collections.disjoint(CITIES, Collections.singleton("Paris")); + + assertThat(isPresent).isTrue(); + } + + @Test + void givenASet_whenUsingCollectionUtilsContainsAnyMethod_thenCheck() { + boolean isPresent = CollectionUtils.containsAny(CITIES, Collections.singleton("Paris")); + + assertThat(isPresent).isTrue(); + } + + @Test + void givenASet_whenUsingSetUtilsIntersectionMethod_thenCheck() { + Set result = SetUtils.intersection(CITIES, Collections.singleton("Tamassint")); + + assertThat(result).isNotEmpty(); + } + +} diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml index cd3e9ed170..d09b0d55e8 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml @@ -86,7 +86,7 @@ 1.8 0.22.6 1.9.20.1 - 0.43 + 0.55.0 1.2.3 0.14.1 1.9.20.1 diff --git a/core-java-modules/core-java-datetime-conversion-2/README.md b/core-java-modules/core-java-datetime-conversion-2/README.md index 7fe174b385..1a2d1b300b 100644 --- a/core-java-modules/core-java-datetime-conversion-2/README.md +++ b/core-java-modules/core-java-datetime-conversion-2/README.md @@ -5,3 +5,4 @@ This module contains articles about converting between Java date and time object ### Relevant Articles: - [Convert Gregorian to Hijri Date in Java](https://www.baeldung.com/java-date-gregorian-hijri-conversion) - [Convert String Date to XMLGregorianCalendar in Java](https://www.baeldung.com/java-string-date-xmlgregoriancalendar-conversion) +- [Convert TemporalAccessor to LocalDate](https://www.baeldung.com/java-temporalaccessor-localdate-conversion) diff --git a/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/TemporalAccessorToLocalDate/TemporalAccessorToLocalDateUnitTest.java b/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/TemporalAccessorToLocalDate/TemporalAccessorToLocalDateUnitTest.java new file mode 100644 index 0000000000..a634fe2a47 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion-2/src/test/java/com/baeldung/TemporalAccessorToLocalDate/TemporalAccessorToLocalDateUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.TemporalAccessorToLocalDate; + +import org.junit.Test; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalQueries; + +import static org.junit.Assert.assertEquals; + +public class TemporalAccessorToLocalDateUnitTest { + String dateString = "2022-03-28"; + TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_LOCAL_DATE.parse(dateString); + + @Test + public void givenTemporalAccessor_whenUsingLocalDateFrom_thenConvertToLocalDate() { + LocalDate convertedDate = LocalDate.from(temporalAccessor); + assertEquals(LocalDate.of(2022, 3, 28), convertedDate); + } + + @Test + public void givenTemporalAccessor_whenUsingTemporalQueries_thenConvertToLocalDate() { + int year = temporalAccessor.query(TemporalQueries.localDate()).getYear(); + int month = temporalAccessor.query(TemporalQueries.localDate()).getMonthValue(); + int day = temporalAccessor.query(TemporalQueries.localDate()).getDayOfMonth(); + + LocalDate convertedDate = LocalDate.of(year, month, day); + assertEquals(LocalDate.of(2022, 3, 28), convertedDate); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/README.md b/core-java-modules/core-java-io-5/README.md index fb050ab2d2..c5054b6f5e 100644 --- a/core-java-modules/core-java-io-5/README.md +++ b/core-java-modules/core-java-io-5/README.md @@ -10,5 +10,7 @@ This module contains articles about core Java input and output (IO) - [Read a File and Split It Into Multiple Files in Java](https://www.baeldung.com/java-read-file-split-into-several) - [Read and Write Files in Java Using Separate Threads](https://www.baeldung.com/java-read-write-files-different-threads) - [Convert an OutputStream to a Byte Array in Java](https://www.baeldung.com/java-outputstream-byte-array) +- [Reading a .gz File Line by Line Using GZIPInputStream](https://www.baeldung.com/java-gzipinputstream-read-gz-file-line-by-line) +- [Opening HTML File Using Java](https://www.baeldung.com/java-open-html-file) - [[<-- Prev]](/core-java-modules/core-java-io-4) diff --git a/core-java-modules/core-java-io-5/src/test/java/com/baeldung/com.baeldung.openhtmlfiles/OpenHtmlFilesUnitTest.java b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/com.baeldung.openhtmlfiles/OpenHtmlFilesUnitTest.java new file mode 100644 index 0000000000..efa58f565b --- /dev/null +++ b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/com.baeldung.openhtmlfiles/OpenHtmlFilesUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.openhtmlfiles; + +import org.junit.Test; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; + +import static org.junit.Assert.*; + +public class OpenHtmlFilesUnitTest { + public URL url; + public String absolutePath; + + public OpenHtmlFilesUnitTest() throws URISyntaxException { + url = getClass().getResource("/test.html"); + assert url != null; + File file = new File(url.toURI()); + if (!file.exists()) { + fail(); + } + absolutePath = file.getAbsolutePath(); + } + /* + @Test + public void givenHtmlFile_whenUsingDesktopClass_thenOpenFileInDefaultBrowser() throws IOException { + File htmlFile = new File(absolutePath); + Desktop.getDesktop().browse(htmlFile.toURI()); + assertTrue(true); + } + */ + @Test + public void givenHtmlFile_whenUsingProcessBuilder_thenOpenFileInDefaultBrowser() throws IOException { + ProcessBuilder pb; + if (System.getProperty("os.name").toLowerCase().contains("win")) { + pb = new ProcessBuilder("cmd.exe", "/c", "start", absolutePath); + } else { + pb = new ProcessBuilder("xdg-open", absolutePath); + } + pb.start(); + assertTrue(true); + } +} diff --git a/core-java-modules/core-java-io-5/src/test/java/com/baeldung/printwriterwritevsprint/WriteVsPrintUnitTest.java b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/printwriterwritevsprint/WriteVsPrintUnitTest.java new file mode 100644 index 0000000000..ad9c0f4619 --- /dev/null +++ b/core-java-modules/core-java-io-5/src/test/java/com/baeldung/printwriterwritevsprint/WriteVsPrintUnitTest.java @@ -0,0 +1,113 @@ +package com.baeldung.printwriterwritevsprint; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class WriteVsPrintUnitTest { + + Object outputFromPrintWriter; + Object outputFromPrintWriter() { + try (BufferedReader br = new BufferedReader(new FileReader("output.txt"))){ + outputFromPrintWriter = br.readLine(); + } catch (IOException e){ + e.printStackTrace(); + Assertions.fail(); + } + return outputFromPrintWriter; + } + + @Test + void whenUsingWriteInt_thenASCIICharacterIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.write(48); + printWriter.close(); + + assertEquals("0", outputFromPrintWriter()); + } + + @Test + void whenUsingWriteCharArrayFromOffset_thenCharArrayIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.write(new char[]{'A','/','&','4','E'}, 1, 4 ); + printWriter.close(); + + assertEquals("/&4E", outputFromPrintWriter()); + } + + @Test + void whenUsingWriteStringFromOffset_thenLengthOfStringIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.write("StringExample", 6, 7 ); + printWriter.close(); + + assertEquals("Example", outputFromPrintWriter()); + } + + @Test + void whenUsingPrintBoolean_thenStringValueIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.print(true); + printWriter.close(); + + assertEquals("true", outputFromPrintWriter()); + } + + @Test + void whenUsingPrintChar_thenCharIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.print('A'); + printWriter.close(); + + assertEquals("A", outputFromPrintWriter()); + } + + @Test + void whenUsingPrintInt_thenValueOfIntIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.print(420); + printWriter.close(); + + assertEquals("420", outputFromPrintWriter()); + } + + @Test + void whenUsingPrintString_thenStringIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + printWriter.print("RandomString"); + printWriter.close(); + + assertEquals("RandomString", outputFromPrintWriter()); + } + + @Test + void whenUsingPrintObject_thenObjectToStringIsPrinted() throws FileNotFoundException { + + PrintWriter printWriter = new PrintWriter("output.txt"); + + Map example = new HashMap(); + + printWriter.print(example); + printWriter.close(); + + assertEquals(example.toString(), outputFromPrintWriter()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-5/src/test/resources/test.html b/core-java-modules/core-java-io-5/src/test/resources/test.html new file mode 100644 index 0000000000..5cb2c410eb --- /dev/null +++ b/core-java-modules/core-java-io-5/src/test/resources/test.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + +

Hello dear friend

+ + \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 29666826a8..c8472f088e 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -11,3 +11,5 @@ This module contains articles about core Java input/output(IO) APIs. - [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference) - [Read Input Character-by-Character in Java](https://www.baeldung.com/java-read-input-character) - [Difference Between flush() and close() in Java FileWriter](https://www.baeldung.com/java-filewriter-flush-vs-close) +- [Get a Path to a Resource in a Java JAR File](https://www.baeldung.com/java-get-path-resource-jar) +- [Java InputStream vs. InputStreamReader](https://www.baeldung.com/java-inputstream-vs-inputstreamreader) diff --git a/core-java-modules/core-java-io-apis-2/pom.xml b/core-java-modules/core-java-io-apis-2/pom.xml index dc33e5338a..dd71f2b53b 100644 --- a/core-java-modules/core-java-io-apis-2/pom.xml +++ b/core-java-modules/core-java-io-apis-2/pom.xml @@ -20,28 +20,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-engine - 5.7.2 - test - - - org.junit.jupiter - junit-jupiter - - - org.junit.jupiter - junit-jupiter - - - org.junit.jupiter - junit-jupiter - - - org.junit.jupiter - junit-jupiter - org.junit.jupiter @@ -63,18 +41,6 @@ ${junit-jupiter-version} test - - org.junit.jupiter - junit-jupiter - - - org.junit.jupiter - junit-jupiter - - - org.junit.jupiter - junit-jupiter - org.testng testng @@ -96,4 +62,5 @@ 5.9.3 - \ No newline at end of file + + diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/getpathtoresource/GetPathToResourceUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/getpathtoresource/GetPathToResourceUnitTest.java new file mode 100644 index 0000000000..27b3e1535d --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/getpathtoresource/GetPathToResourceUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.getpathtoresource; + +import org.junit.Test; + +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +import static org.junit.Assert.assertNotNull; + +public class GetPathToResourceUnitTest { + + @Test + public void givenFile_whenClassUsed_thenGetResourcePath() { + URL resourceUrl = GetPathToResourceUnitTest.class.getResource("/sampleText1.txt"); + assertNotNull(resourceUrl); + } + + @Test + public void givenFile_whenClassLoaderUsed_thenGetResourcePath() { + URL resourceUrl = GetPathToResourceUnitTest.class.getClassLoader().getResource("sampleText1.txt"); + assertNotNull(resourceUrl); + } + + @Test + public void givenFile_whenPathUsed_thenGetResourcePath() throws Exception { + Path resourcePath = Paths.get(Objects.requireNonNull(GetPathToResourceUnitTest.class.getResource("/sampleText1.txt")).toURI()); + assertNotNull(resourcePath); + } + +} diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/inputstreamreader/InputStreamReaderUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/inputstreamreader/InputStreamReaderUnitTest.java new file mode 100644 index 0000000000..d67b56e10b --- /dev/null +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/inputstreamreader/InputStreamReaderUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.inputstreamreader; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +public class InputStreamReaderUnitTest { + @Test + public void givenAStringWrittenToAFile_whenReadByInputStreamReader_thenShouldMatchWhenRead(@TempDir Path tempDir) throws IOException { + String sampleTxt = "Good day. This is just a test. Good bye."; + Path sampleOut = tempDir.resolve("sample-out.txt"); + List lines = Arrays.asList(sampleTxt); + Files.write(sampleOut, lines); + String absolutePath = String.valueOf(sampleOut.toAbsolutePath()); + try (InputStreamReader reader = new InputStreamReader(new FileInputStream(absolutePath), StandardCharsets.UTF_8)) { + boolean isMatched = false; + int b; + StringBuilder sb = new StringBuilder(); + while ((b = reader.read()) != -1) { + sb.append((char) b); + if (sb.toString().contains(sampleTxt)) { + isMatched = true; + break; + } + } + assertThat(isMatched).isTrue(); + } + } +} diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index 460adf45e7..e87fba922e 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -260,7 +260,6 @@ 0.4 1.8.7 - 4.6.1 1.1 3.6.2 diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index d4eef0f1b9..473369beef 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -7,15 +7,11 @@ - [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string) - [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables) - [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation) -- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) - [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation) - [Java Program to Print Pascal’s Triangle](https://www.baeldung.com/java-pascal-triangle) - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) - [Clamp Function in Java](https://www.baeldung.com/java-clamp-function) - [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square) -- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) - [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation) -- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point) - [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow) -- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math-4/README.md b/core-java-modules/core-java-lang-math-4/README.md index 377c51848d..0efe87f7ff 100644 --- a/core-java-modules/core-java-lang-math-4/README.md +++ b/core-java-modules/core-java-lang-math-4/README.md @@ -2,3 +2,7 @@ ### Relevant articles: - [Calculate Percentiles in Java](https://www.baeldung.com/java-compute-percentiles) +- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem) +- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point) +- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) +- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) diff --git a/core-java-modules/core-java-lang-math-4/pom.xml b/core-java-modules/core-java-lang-math-4/pom.xml index e818855d36..ccafb4a894 100644 --- a/core-java-modules/core-java-lang-math-4/pom.xml +++ b/core-java-modules/core-java-lang-math-4/pom.xml @@ -12,4 +12,8 @@ 0.0.1-SNAPSHOT + + 17 + + diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-constructors-2/README.md b/core-java-modules/core-java-lang-oop-constructors-2/README.md index d9b162c7a6..1357dfc1c5 100644 --- a/core-java-modules/core-java-lang-oop-constructors-2/README.md +++ b/core-java-modules/core-java-lang-oop-constructors-2/README.md @@ -4,4 +4,5 @@ This module contains article about constructors in Java ### Relevant Articles: - [Different Ways to Create an Object in Java](https://www.baeldung.com/java-different-ways-to-create-objects) -- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-oop-constructors) \ No newline at end of file +- [When to Use Setter Methods or Constructors for Setting a Variable’s Value in Java](https://www.baeldung.com/java-setter-method-vs-constructor) +- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-oop-constructors) diff --git a/core-java-modules/core-java-lang-oop-others/README.md b/core-java-modules/core-java-lang-oop-others/README.md index ffd1d47f79..e4970553bd 100644 --- a/core-java-modules/core-java-lang-oop-others/README.md +++ b/core-java-modules/core-java-lang-oop-others/README.md @@ -10,3 +10,4 @@ This module contains articles about Object Oriented Programming (OOP) in Java - [Law of Demeter in Java](https://www.baeldung.com/java-demeter-law) - [Java Interface Naming Conventions](https://www.baeldung.com/java-interface-naming-conventions) - [Difference Between Information Hiding and Encapsulation](https://www.baeldung.com/java-information-hiding-vs-encapsulation) +- [Statements Before super() in Java](https://www.baeldung.com/java-statements-before-super-constructor) diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java new file mode 100644 index 0000000000..0557e032ad --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java @@ -0,0 +1,13 @@ +package com.baeldung.passclassasparameter; + +public class Example { + public static void processClass(Class clazz) { + System.out.println("Processing class: " + clazz.getName()); + } + + public static void main(String[] args) { + processClass(String.class); + processClass(Integer.class); + processClass(Double.class); + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java new file mode 100644 index 0000000000..c72d57743c --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java @@ -0,0 +1,22 @@ +package com.baeldung.passclassasparameter; + +import java.util.ArrayList; +import java.util.List; + +public class GenericExample { + public static void printListElements(Class clazz, List list) { + System.out.println("Elements of " + clazz.getSimpleName() + " list:"); + for (T element : list) { + System.out.println(element); + } + } + + public static void main(String[] args) { + List stringList = new ArrayList<>(); + stringList.add("Java"); + stringList.add("is"); + stringList.add("awesome"); + + printListElements(String.class, stringList); + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java new file mode 100644 index 0000000000..04c9dc3414 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java @@ -0,0 +1,21 @@ +package com.baeldung.passclassasparameter; + +import java.lang.reflect.Method; + +public class ReflectionExample { + public static void processClass(Class clazz, String methodName) throws Exception { + Method method = clazz.getMethod(methodName); + Object instance = clazz.getDeclaredConstructor().newInstance(); + method.invoke(instance); + } + + public static void main(String[] args) throws Exception { + processClass(ReflectionTarget.class, "sayHello"); + } +} + +class ReflectionTarget { + public void sayHello() { + System.out.println("Hello, Reflection!"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Child.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Child.java new file mode 100644 index 0000000000..6b8fda032c --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Child.java @@ -0,0 +1,14 @@ +package com.baeldung.statementsbeforesuper; + +class Child extends Parent { + Child() { + super(); // Or super(10); Correct placements + System.out.println("Child constructor"); + additionalInitialization(); + // super(); Compilation error: Constructor call must be the first statement in a constructor + } + + private void additionalInitialization() { + System.out.println("Additional initialization in Child"); + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Parent.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Parent.java new file mode 100644 index 0000000000..38ed9ecd1a --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/statementsbeforesuper/Parent.java @@ -0,0 +1,11 @@ +package com.baeldung.statementsbeforesuper; + +public class Parent { + public Parent(int id) { + System.out.println("Parametrized Parent constructor"); + } + + public Parent() { + System.out.println("Parent constructor"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerIntegrationTest.java b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerIntegrationTest.java index e3100deebc..edafe242c1 100644 --- a/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerIntegrationTest.java +++ b/core-java-modules/core-java-networking-2/src/test/java/com/baeldung/url/UrlCheckerIntegrationTest.java @@ -11,28 +11,28 @@ public class UrlCheckerIntegrationTest { @Test public void givenValidUrl_WhenUsingHEAD_ThenReturn200() throws IOException { UrlChecker tester = new UrlChecker(); - int responseCode = tester.getResponseCodeForURLUsingHead("http://www.example.com"); + int responseCode = tester.getResponseCodeForURLUsingHead("https://httpbin.org/status/200"); assertEquals(200, responseCode); } @Test public void givenInvalidIUrl_WhenUsingHEAD_ThenReturn404() throws IOException { UrlChecker tester = new UrlChecker(); - int responseCode = tester.getResponseCodeForURLUsingHead("http://www.example.com/xyz"); + int responseCode = tester.getResponseCodeForURLUsingHead("https://httpbin.org/status/404"); assertEquals(404, responseCode); } @Test public void givenValidUrl_WhenUsingGET_ThenReturn200() throws IOException { UrlChecker tester = new UrlChecker(); - int responseCode = tester.getResponseCodeForURL("http://www.example.com"); + int responseCode = tester.getResponseCodeForURL("https://httpbin.org/status/200"); assertEquals(200, responseCode); } @Test public void givenInvalidIUrl_WhenUsingGET_ThenReturn404() throws IOException { UrlChecker tester = new UrlChecker(); - int responseCode = tester.getResponseCodeForURL("http://www.example.com/xyz"); + int responseCode = tester.getResponseCodeForURL("https://httpbin.org/status/404"); assertEquals(404, responseCode); } diff --git a/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumber.java b/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumber.java new file mode 100644 index 0000000000..c969e43f86 --- /dev/null +++ b/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumber.java @@ -0,0 +1,43 @@ +import java.util.Map; + +public class UseHashMapToConvertPhoneNumberInWordsToNumber { + private static Map multipliers = Map.of("double",2, + "triple", 3, + "quadruple", 4); + private static Map digits = Map.of("zero","1", + "one", "1", + "two", "2", + "three", "3", + "four", "4", + "five", "5", + "six", "6", + "seven", "7", + "eight", "8", + "nine", "9"); + + + public static String convertPhoneNumberInWordsToNumber(String phoneNumberInWord) { + + StringBuilder output = new StringBuilder(); + Integer currentMultiplier = null; + String[] words = phoneNumberInWord.split(" "); + + for (String word : words) { + Integer multiplier = multipliers.get(word); + if (multiplier != null) { + if (currentMultiplier != null) { + throw new IllegalArgumentException("Cannot have consecutive multipliers, at: " + word); + } + currentMultiplier = multiplier; + } else { + String digit = digits.get(word); + if (digit == null) { + throw new IllegalArgumentException("Invalid word: " + word); + } + output.append(digit.repeat(currentMultiplier != null ? currentMultiplier : 1)); + currentMultiplier = null; + } + } + return output.toString(); + } +} diff --git a/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumber.java b/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumber.java new file mode 100644 index 0000000000..69f9ce9ab7 --- /dev/null +++ b/core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumber.java @@ -0,0 +1,64 @@ +public class UseSwitchToConvertPhoneNumberInWordsToNumber { + + public static String convertPhoneNumberInWordsToNumber(String phoneNumberInWord) { + + StringBuilder output = new StringBuilder(); + Integer currentMultiplier = null; + String[] words = phoneNumberInWord.split(" "); + + for (String word : words) { + Integer multiplier = getWordAsMultiplier(word); + if (multiplier != null) { + if (currentMultiplier != null) { + throw new IllegalArgumentException("Cannot have consecutive multipliers, at: " + word); + } + currentMultiplier = multiplier; + } else { + output.append(getWordAsDigit(word).repeat(currentMultiplier != null ? currentMultiplier : 1)); + currentMultiplier = null; + } + } + return output.toString(); + } + + public static Integer getWordAsMultiplier(String word) { + switch (word) { + case "double": + return 2; + case "triple": + return 3; + case "quadruple": + return 4; + default: + return null; + } + } + + public static String getWordAsDigit(String word) { + switch (word) { + case "zero": + return "0"; + case "one": + return "1"; + case "two": + return "2"; + case "three": + return "3"; + case "four": + return "4"; + case "five": + return "5"; + case "six": + return "6"; + case "seven": + return "7"; + case "eight": + return "8"; + case "nine": + return "9"; + default: + throw new IllegalArgumentException("Invalid word: " + word); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumberUnitTest.java b/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumberUnitTest.java new file mode 100644 index 0000000000..95a50dd16e --- /dev/null +++ b/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseHashMapToConvertPhoneNumberInWordsToNumberUnitTest.java @@ -0,0 +1,31 @@ +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class UseHashMapToConvertPhoneNumberInWordsToNumberUnitTest { + + @Test + void givenStringWithWhiteSpaces_WhenConvertPhoneNumberInWordsToNumber_ThenEquivalentNumber() { + + assertEquals("5248888", + UseHashMapToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five two four quadruple eight")); + } + + @Test + void givenStringEndingWithConseutiveMultipliers_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() { + + assertThrows(IllegalArgumentException.class, () -> { + UseHashMapToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five eight three double triple"); + }); + } + + @Test + void givenStringWithInvalidWords_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() { + + assertThrows(IllegalArgumentException.class, () -> { + UseHashMapToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five eight three two four penta null eight"); + }); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumberUnitTest.java b/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumberUnitTest.java new file mode 100644 index 0000000000..093e96ecea --- /dev/null +++ b/core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/convertphonenumberinwordstonumber/UseSwitchToConvertPhoneNumberInWordsToNumberUnitTest.java @@ -0,0 +1,62 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UseSwitchToConvertPhoneNumberInWordsToNumberUnitTest { + + @Test + void givenStringWithWhiteSpaces_WhenConvertPhoneNumberInWordsToNumber_ThenEquivalentNumber() { + + assertEquals("5248888", + UseSwitchToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five two four quadruple eight")); + + } + + @Test + void givenStringEndingWithConseutiveMultipliers_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() { + + assertThrows(IllegalArgumentException.class, () -> { + UseSwitchToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five eight three double triple"); + }); + } + + @Test + void givenStringWithInvalidWords_WhenConvertPhoneNumberInWordsToNumber_ThenThrowException() { + + assertThrows(IllegalArgumentException.class, () -> { + UseSwitchToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("five eight three two four penta null eight"); + }); + } + + + @Test + void givenString_WhenGetWordAsMultiplier_ThenEquivalentNumber() { + assertEquals(2, UseSwitchToConvertPhoneNumberInWordsToNumber + .getWordAsMultiplier("double")); + } + + @Test + void givenInvalidString_WhenGetWordAsMultiplier_ThenReturnNull() { + assertEquals(null, UseSwitchToConvertPhoneNumberInWordsToNumber + .getWordAsMultiplier("hexa")); + + } + + @Test + void givenString_WhenMapIndividualDigits_ThenEquivalentNumber() { + assertEquals("5", + UseSwitchToConvertPhoneNumberInWordsToNumber + .getWordAsDigit("five")); + } + + @Test + void givenInvalidString_WhenMapIndividualDigits_ThenThrowException() { + assertThrows(IllegalArgumentException.class, () -> { + UseSwitchToConvertPhoneNumberInWordsToNumber + .convertPhoneNumberInWordsToNumber("penta"); + }); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/pom.xml b/core-java-modules/core-java-reflection-2/pom.xml index 69cf4f5f37..41d2b0a7ae 100644 --- a/core-java-modules/core-java-reflection-2/pom.xml +++ b/core-java-modules/core-java-reflection-2/pom.xml @@ -49,7 +49,7 @@ org.jacoco jacoco-maven-plugin - 0.8.8 + ${jacoco-maven-plugin.version} @@ -73,6 +73,7 @@ 1.8 1.8 5.3.4 + 0.8.11 \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-3/pom.xml b/core-java-modules/core-java-reflection-3/pom.xml index e4111b8dda..61bc424336 100644 --- a/core-java-modules/core-java-reflection-3/pom.xml +++ b/core-java-modules/core-java-reflection-3/pom.xml @@ -49,7 +49,7 @@ org.jacoco jacoco-maven-plugin - 0.8.8 + ${jacoco-maven-plugin.version} @@ -73,6 +73,7 @@ 1.8 1.8 5.3.4 + 0.8.11 \ No newline at end of file diff --git a/core-java-modules/core-java-streams-maps/README.md b/core-java-modules/core-java-streams-maps/README.md index 8f311d91a5..0f6796f262 100644 --- a/core-java-modules/core-java-streams-maps/README.md +++ b/core-java-modules/core-java-streams-maps/README.md @@ -1,3 +1,4 @@ ## Relevant Articles: - [Handle Duplicate Keys When Producing Map Using Java Stream](https://www.baeldung.com/java-duplicate-keys-when-producing-map-using-stream) -- [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) \ No newline at end of file +- [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) +- [Flatten a Stream of Maps to a Single Map in Java](https://www.baeldung.com/java-flatten-stream-map) diff --git a/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java b/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java new file mode 100644 index 0000000000..b23dd07fc8 --- /dev/null +++ b/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java @@ -0,0 +1,143 @@ +package com.baeldung.streams.mapstreamtomap; + +import static java.lang.Math.max; +import static java.util.stream.Collectors.flatMapping; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.reducing; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +public class MapStreamToMapUnitTest { + + Map playerMap1 = new HashMap() {{ + put("Kai", 92); + put("Liam", 100); + }}; + Map playerMap2 = new HashMap() {{ + put("Eric", 42); + put("Kevin", 77); + }}; + Map playerMap3 = new HashMap() {{ + put("Saajan", 35); + }}; + Map playerMap4 = new HashMap() {{ + put("Kai", 76); + }}; + Map playerMap5 = new HashMap() {{ + put("Kai", null); + put("Jerry", null); + }}; + + @Test + void givenMapsStream_whenUsingFlatMapAndToMap_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); + put("Eric", 42); + put("Kevin", 77); + }}; + + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + assertEquals(expectedMap, mergedMap); + } + + @Test + void givenMapsWithDuplicateKeys_whenUsingFlatMapAndToMap_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 76 and 92 + put("Eric", 42); + put("Kevin", 77); + }}; + + assertThrows(IllegalStateException.class, () -> Stream.of(playerMap1, playerMap2, playerMap3, playerMap4) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)), "Duplicate key Kai (attempted merging values 92 and 76)"); + + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3, playerMap4) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max)); + + assertEquals(expectedMap, mergedMap); + } + + private Integer maxInteger(Integer int1, Integer int2) { + if (int1 == null) { + return int2; + } + if (int2 == null) { + return int1; + } + return max(int1, int2); + } + + @Test + void givenMapsWithDuplicateKeysAndNullValues_whenUsingFlatMapWithForEach_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 92, 76, and null + put("Eric", 42); + put("Kevin", 77); + put("Jerry", null); + }}; + + assertThrows(NullPointerException.class, () -> Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max))); + + Map mergedMap = new HashMap<>(); + Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(map -> map.entrySet() + .stream()) + .forEach(entry -> { + String k = entry.getKey(); + Integer v = entry.getValue(); + if (mergedMap.containsKey(k)) { + mergedMap.put(k, maxInteger(mergedMap.get(k), v)); + } else { + mergedMap.put(k, v); + } + }); + assertEquals(expectedMap, mergedMap); + + } + + @Test + void givenMapsWithDuplicateKeysAndNullValues_whenUsingReduce_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 92, 76, and null + put("Eric", 42); + put("Kevin", 77); + put("Jerry", null); + }}; + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(x -> x.entrySet() + .stream()) + .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, reducing(null, this::maxInteger)))); + assertEquals(expectedMap, mergedMap); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-8/README.md b/core-java-modules/core-java-string-operations-8/README.md index 22407a5961..018fcdc987 100644 --- a/core-java-modules/core-java-string-operations-8/README.md +++ b/core-java-modules/core-java-string-operations-8/README.md @@ -6,3 +6,6 @@ - [Get First n Characters in a String in Java](https://www.baeldung.com/get-first-n-characters-in-a-string-in-java) - [Remove Only Trailing Spaces or Whitespace From a String in Java](https://www.baeldung.com/java-string-remove-only-trailing-whitespace) - [Get the Initials of a Name in Java](https://www.baeldung.com/java-shorten-name-initials) +- [Normalizing the EOL Character in Java](https://www.baeldung.com/java-normalize-end-of-line-character) +- [Converting UTF-8 to ISO-8859-1 in Java](https://www.baeldung.com/java-utf-8-iso-8859-1-conversion) +- [Get Last n Characters From a String](https://www.baeldung.com/java-string-get-last-n-characters) diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/lastncharacters/LastNCharactersUnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/lastncharacters/LastNCharactersUnitTest.java new file mode 100644 index 0000000000..0d30653082 --- /dev/null +++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/lastncharacters/LastNCharactersUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.lastncharacters; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class LastNCharactersUnitTest { + + private String s; + private int n; + + @BeforeEach + void init() { + s = "10-03-2024"; + n = 4; + } + + @Test + void givenString_whenUsingIntStreamAsStreamSource_thenObtainLastNCharacters() { + String result = s.chars() + .mapToObj(c -> (char) c) + .skip(s.length() - n) + .map(String::valueOf) + .collect(Collectors.joining()); + + assertThat(result).isEqualTo("2024"); + } + + @Test + void givenString_whenUsingOneArgSubstringMethod_thenObtainLastNCharacters() { + int beginIndex = s.length() - n; + + assertThat(s.substring(beginIndex)).isEqualTo("2024"); + } + + @Test + void givenString_whenUsingStreamOfCharactersAsSource_thenObtainLastNCharacters() { + String result = Arrays.stream(ArrayUtils.toObject(s.toCharArray())) + .skip(s.length() - n) + .map(String::valueOf) + .collect(Collectors.joining()); + + assertThat(result).isEqualTo("2024"); + } + + @Test + void givenString_whenUsingStringUtilsRight_thenObtainLastNCharacters() { + assertThat(StringUtils.right(s, n)).isEqualTo("2024"); + } + + @Test + void givenString_whenUsingTwoArgSubstringMethod_thenObtainLastNCharacters() { + int beginIndex = s.length() - n; + String result = s.substring(beginIndex, s.length()); + + assertThat(result).isEqualTo("2024"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java new file mode 100644 index 0000000000..ff94aeaea8 --- /dev/null +++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java @@ -0,0 +1,74 @@ +package com.baeldung.symmetricsubstringlength; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SymmetricSubstringMaxLengthUnitTest { + String input = "abba"; + int expected = 4; + + static int findLongestSymmetricSubstringUsingSymmetricApproach(String str) { + int maxLength = 1; + + for (int i = 0; i < str.length(); i++) { + for (int j = i; j < str.length(); j++) { + int flag = 1; + for (int k = 0; k < (j - i + 1) / 2; k++) { + if (str.charAt(i + k) != str.charAt(j - k)) { + flag = 0; + break; + } + } + if (flag != 0 && (j - i + 1) > maxLength) { + maxLength = j - i + 1; + } + } + } + return maxLength; + } + + @Test + public void givenString_whenUsingBruteForce_thenFindLongestSymmetricSubstring() { + assertEquals(expected, findLongestSymmetricSubstringUsingBruteForce(input).length()); + } + + @Test + public void givenString_whenUsingSymmetricSubstring_thenFindLongestSymmetricSubstring() { + assertEquals(expected, findLongestSymmetricSubstringUsingSymmetricApproach(input)); + } + + private String findLongestSymmetricSubstringUsingBruteForce(String str) { + if (str == null || str.length() == 0) { + return ""; + } + + int maxLength = 0; + String longestPalindrome = ""; + + for (int i = 0; i < str.length(); i++) { + for (int j = i + 1; j <= str.length(); j++) { + String substring = str.substring(i, j); + if (isPalindrome(substring) && substring.length() > maxLength) { + maxLength = substring.length(); + longestPalindrome = substring; + } + } + } + + return longestPalindrome; + } + + private boolean isPalindrome(String s) { + int left = 0; + int right = s.length() - 1; + while (left < right) { + if (s.charAt(left) != s.charAt(right)) { + return false; + } + left++; + right--; + } + return true; + } +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 85df51457c..f6c5f8191a 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -89,6 +89,7 @@ core-java-collections-3 core-java-collections-4 core-java-collections-5 + core-java-collections-6 core-java-collections-conversions core-java-collections-set-2 core-java-collections-list @@ -99,6 +100,7 @@ core-java-collections-maps-2 core-java-collections-maps-3 core-java-collections-maps-7 + core-java-collections-maps-8 core-java-compiler core-java-concurrency-2 core-java-concurrency-advanced diff --git a/docker-modules/docker-caching/README.md b/docker-modules/docker-caching/README.md deleted file mode 100644 index d985210683..0000000000 --- a/docker-modules/docker-caching/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant Articles: - -- [Caching Maven Dependencies with Docker](https://www.baeldung.com/ops/docker-cache-maven-dependencies) diff --git a/docker-modules/docker-caching/multi-module-caching/Dockerfile b/docker-modules/docker-caching/multi-module-caching/Dockerfile deleted file mode 100644 index 96ebe2a76b..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM maven:alpine as build -ENV HOME=/usr/app -RUN mkdir -p $HOME -WORKDIR $HOME - -ADD pom.xml $HOME -ADD core/pom.xml $HOME/core/pom.xml -ADD runner/pom.xml $HOME/runner/pom.xml - -RUN mvn -pl core verify --fail-never -ADD core $HOME/core -RUN mvn -pl core install -RUN mvn -pl runner verify --fail-never -ADD runner $HOME/runner -RUN mvn -pl core,runner package - -FROM openjdk:8-jdk-alpine - -COPY --from=build /usr/app/runner/target/runner-0.0.1-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar - -ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/Dockerfile-Buildkit b/docker-modules/docker-caching/multi-module-caching/Dockerfile-Buildkit deleted file mode 100644 index e89ce38e4b..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/Dockerfile-Buildkit +++ /dev/null @@ -1,13 +0,0 @@ -FROM maven:alpine as build -ENV HOME=/usr/app -RUN mkdir -p $HOME -WORKDIR $HOME - -ADD . $HOME -RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package - -FROM openjdk:8-jdk-alpine - -COPY --from=build /usr/app/runner/target/runner-0.0.1-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar - -ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/core-module/pom.xml b/docker-modules/docker-caching/multi-module-caching/core-module/pom.xml deleted file mode 100644 index 991162ddfa..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/core-module/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - 4.0.0 - core-module - - - multi-module-caching - com.baeldung - 0.0.1-SNAPSHOT - - - - - com.google.guava - guava - ${guava.version} - - - - - 8 - 8 - 33.0.0-jre - - - \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/core-module/src/main/java/com/baeldung/maven_caching/CoreClass.java b/docker-modules/docker-caching/multi-module-caching/core-module/src/main/java/com/baeldung/maven_caching/CoreClass.java deleted file mode 100644 index d8c73a331a..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/core-module/src/main/java/com/baeldung/maven_caching/CoreClass.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.maven_caching; - -import com.google.common.io.Files; - -public class CoreClass { - - public String method() { - return "Hello from core module!!"; - } - - public String dependencyMethod() { - return Files.simplifyPath("/home/app/test"); - } -} diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml deleted file mode 100644 index 3e9859a8d1..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - 4.0.0 - com.baeldung - multi-module-caching - 0.0.1-SNAPSHOT - pom - Multi-module Maven caching example - - - runner-module - core-module - - - - - - com.google.guava - guava - ${guava.version} - - - - - - 33.0.0-jre - - - \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml b/docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml deleted file mode 100644 index 8d6bba9183..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/runner-module/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - 4.0.0 - runner-module - - - multi-module-caching - com.baeldung - 0.0.1-SNAPSHOT - - - - - com.baeldung - core-module - 0.0.1-SNAPSHOT - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - ${maven-assembly-plugin.version} - - - jar-with-dependencies - - - - true - com.baeldung.maven_caching.MavenCachingApplication - - - - - - assemble-all - package - - single - - - - - - - - - 3.3.0 - 8 - 8 - - - \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/runner-module/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java b/docker-modules/docker-caching/multi-module-caching/runner-module/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java deleted file mode 100644 index 3673dd86c1..0000000000 --- a/docker-modules/docker-caching/multi-module-caching/runner-module/src/main/java/com/baeldung/maven_caching/MavenCachingApplication.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.maven_caching; - -public class MavenCachingApplication { - - public static void main(String[] args) { - CoreClass cc = new CoreClass(); - System.out.println(cc.method()); - System.out.println(cc.dependencyMethod()); - } - -} diff --git a/docker-modules/docker-caching/pom.xml b/docker-modules/docker-caching/pom.xml deleted file mode 100644 index 83cb7be9af..0000000000 --- a/docker-modules/docker-caching/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - 4.0.0 - docker-caching - pom - docker-caching - - - docker-modules - com.baeldung - 1.0.0-SNAPSHOT - - - - single-module-caching - multi-module-caching - - - \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/Dockerfile b/docker-modules/docker-caching/single-module-caching/Dockerfile deleted file mode 100644 index 02157c0dd6..0000000000 --- a/docker-modules/docker-caching/single-module-caching/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM maven:alpine as build -ENV HOME=/usr/app -RUN mkdir -p $HOME -WORKDIR $HOME -ADD pom.xml $HOME -RUN mvn verify --fail-never - -ADD . $HOME -RUN mvn package - -FROM openjdk:8-jdk-alpine - -COPY --from=build /usr/app/target/single-module-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar - -ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/Dockerfile-Buildkit b/docker-modules/docker-caching/single-module-caching/Dockerfile-Buildkit deleted file mode 100644 index 29384ce208..0000000000 --- a/docker-modules/docker-caching/single-module-caching/Dockerfile-Buildkit +++ /dev/null @@ -1,13 +0,0 @@ -FROM maven:alpine as build -ENV HOME=/usr/app -RUN mkdir -p $HOME -WORKDIR $HOME -ADD . $HOME - -RUN --mount=type=cache,target=/root/.m2 mvn -f $HOME/pom.xml clean package - -FROM openjdk:8-jdk-alpine - -COPY --from=build /usr/app/target/single-module-caching-1.0-SNAPSHOT-jar-with-dependencies.jar /app/runner.jar - -ENTRYPOINT java -jar /app/runner.jar \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml deleted file mode 100644 index 3360360742..0000000000 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - com.baeldung - single-module-caching - 1.0-SNAPSHOT - - - - com.google.guava - guava - ${guava.version} - - - - - - - org.apache.maven.plugins - maven-assembly-plugin - ${maven-assembly-plugin.version} - - - jar-with-dependencies - - - - true - com.baeldung.maven_caching.MavenCachingMain - - - - - - assemble-all - package - - single - - - - - - - - - 8 - 8 - UTF-8 - 33.0.0-jre - 3.3.0 - - - \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java b/docker-modules/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java deleted file mode 100644 index 4fbd8e5311..0000000000 --- a/docker-modules/docker-caching/single-module-caching/src/main/java/com/baeldung/maven_caching/MavenCachingMain.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung.maven_caching; - -import com.google.common.io.Files; - -public class MavenCachingMain { - - public static void main(String[] args) { - System.out.println("Hello from maven_caching app!!!"); - System.out.println(Files.simplifyPath("/home/app/test")); - } -} diff --git a/docker-modules/docker-compose-2/README.md b/docker-modules/docker-compose-2/README.md deleted file mode 100644 index 353b85f154..0000000000 --- a/docker-modules/docker-compose-2/README.md +++ /dev/null @@ -1,2 +0,0 @@ -## Relevant Articles: -- [Communicating With Docker Containers on the Same Machine](https://www.baeldung.com/ops/docker-communicating-with-containers-on-same-machine) diff --git a/docker-modules/docker-compose-2/communication_same_machine/Dockerfile b/docker-modules/docker-compose-2/communication_same_machine/Dockerfile deleted file mode 100644 index a0c4ebe59a..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine:latest -MAINTAINER baeldung.com -RUN apk update && apk add iputils && apk add bash && apk add curl \ No newline at end of file diff --git a/docker-modules/docker-compose-2/communication_same_machine/Dockerfile.node b/docker-modules/docker-compose-2/communication_same_machine/Dockerfile.node deleted file mode 100644 index 6d8f0eff81..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/Dockerfile.node +++ /dev/null @@ -1,7 +0,0 @@ -FROM node:8.16.1-alpine -WORKDIR /app -COPY host_docker_internal/package.json /app -COPY host_docker_internal/index.js /app -RUN npm install -CMD node index.js -EXPOSE 8080 \ No newline at end of file diff --git a/docker-modules/docker-compose-2/communication_same_machine/dns/docker-compose.yml b/docker-modules/docker-compose-2/communication_same_machine/dns/docker-compose.yml deleted file mode 100644 index 0a06993241..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/dns/docker-compose.yml +++ /dev/null @@ -1,20 +0,0 @@ -services: - alpine-app-1: - container_name: alpine-app-1 - image: alpine-app-1 - build: - context: .. - dockerfile: Dockerfile - tty: true - ports: - - 8081:8081 - - alpine-app-2: - container_name: alpine-app-2 - image: alpine-app-2 - build: - context: .. - dockerfile: Dockerfile - tty: true - ports: - - 8080:8080 diff --git a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/docker-compose.yml b/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/docker-compose.yml deleted file mode 100644 index 8e7174a9a1..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/docker-compose.yml +++ /dev/null @@ -1,29 +0,0 @@ -services: - alpine-app-1: - container_name: alpine-app-1 - extra_hosts: # for linux hosts since version 20.10 - - host.docker.internal:host-gateway - build: - context: .. - dockerfile: Dockerfile - image: alpine-app-1 - tty: true - networks: - - first-network - - node-app: - container_name: node-app - build: - context: .. - dockerfile: Dockerfile.node - image: node-app - ports: - - 8080:8080 - networks: - - second-network - -networks: - first-network: - driver: bridge - second-network: - driver: bridge \ No newline at end of file diff --git a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/index.js b/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/index.js deleted file mode 100644 index cefae028e5..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/index.js +++ /dev/null @@ -1,10 +0,0 @@ -var express = require('express') -var app = express() - -app.get('/', function (req, res) { - res.send('Hello World!') -}) - -app.listen(8080, function () { - console.log('app listening on port 8080!') -}) \ No newline at end of file diff --git a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/package.json b/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/package.json deleted file mode 100644 index cde98b1cfd..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/host_docker_internal/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "host_docker_internal", - "version": "1.0.0", - "description": "node js app", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Baeldung", - "license": "ISC", - "dependencies": { - "express": "^4.18.2" - } -} diff --git a/docker-modules/docker-compose-2/communication_same_machine/static_ip_bridge/docker-compose.yml b/docker-modules/docker-compose-2/communication_same_machine/static_ip_bridge/docker-compose.yml deleted file mode 100644 index 0193bd72fb..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/static_ip_bridge/docker-compose.yml +++ /dev/null @@ -1,34 +0,0 @@ -services: - alpine-app-1: - container_name: alpine-app-1 - build: - context: .. - dockerfile: Dockerfile - image: alpine-app-1 - tty: true - ports: - - 8080:8080 - networks: - network-example: - ipv4_address: 10.5.0.2 - - alpine-app-2: - container_name: alpine-app-2 - build: - context: .. - dockerfile: Dockerfile - image: alpine-app-2 - tty: true - ports: - - 8081:8081 - networks: - network-example: - ipv4_address: 10.5.0.3 - -networks: - network-example: - driver: bridge - ipam: - config: - - subnet: 10.5.0.0/16 - gateway: 10.5.0.1 \ No newline at end of file diff --git a/docker-modules/docker-compose-2/communication_same_machine/static_ip_macvlan/docker-compose.yml b/docker-modules/docker-compose-2/communication_same_machine/static_ip_macvlan/docker-compose.yml deleted file mode 100644 index cef1a0b5cb..0000000000 --- a/docker-modules/docker-compose-2/communication_same_machine/static_ip_macvlan/docker-compose.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - alpine-app-1: - container_name: alpine-app-1 - build: - context: .. - dockerfile: Dockerfile - image: alpine-app-1 - tty: true - ports: - - 8080:8080 - networks: - network-example: - ipv4_address: 192.168.2.2 - - alpine-app-2: - container_name: alpine-app-2 - build: - context: .. - dockerfile: Dockerfile - image: alpine-app-2 - tty: true - ports: - - 8081:8081 - networks: - network-example: - ipv4_address: 192.168.2.3 - -networks: - network-example: - driver: macvlan - driver_opts: - parent: enp0s3 - ipam: - config: - - subnet: 192.168.2.0/24 - gateway: 192.168.2.1 \ No newline at end of file diff --git a/docker-modules/docker-compose-2/pom.xml b/docker-modules/docker-compose-2/pom.xml deleted file mode 100644 index 9d06aeb477..0000000000 --- a/docker-modules/docker-compose-2/pom.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - 4.0.0 - docker-compose-2 - pom - Demo project for Spring Boot and Docker - Module docker-compose-2 - - - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 - - - \ No newline at end of file diff --git a/docker-modules/docker-compose/Dockerfile b/docker-modules/docker-compose/Dockerfile deleted file mode 100644 index 382e1d3442..0000000000 --- a/docker-modules/docker-compose/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM openjdk:17-alpine -MAINTAINER baeldung.com -COPY target/docker-compose-0.0.1-SNAPSHOT.jar app.jar -ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/docker-modules/docker-compose/README.md b/docker-modules/docker-compose/README.md deleted file mode 100644 index 603debe6a1..0000000000 --- a/docker-modules/docker-compose/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## Relevant Articles: - -- [Introduction to Docker Compose](https://www.baeldung.com/ops/docker-compose) -- [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image) -- [Communication Between Multiple Docker Compose Projects](https://www.baeldung.com/ops/docker-compose-communication) -- [Difference Between links and depends_on in Docker Compose](https://www.baeldung.com/ops/docker-compose-links-depends-on) -- [Mounting Multiple Volumes on a Docker Container](https://www.baeldung.com/ops/docker-mounting-multiple-volumes) -- [Rebuild Docker Container in Docker Compose](https://www.baeldung.com/ops/rebuild-docker-container-compose) -- [Assign Static IP to Docker Container and Docker-Compose](https://www.baeldung.com/ops/docker-assign-static-ip-container) -- [Exclude a Sub-Folder When Adding a Volume to Docker](https://www.baeldung.com/ops/docker-exclude-sub-folder-when-adding-volume) diff --git a/docker-modules/docker-compose/assign-static-ip/docker-compose.yml b/docker-modules/docker-compose/assign-static-ip/docker-compose.yml deleted file mode 100644 index 9f555d1ad4..0000000000 --- a/docker-modules/docker-compose/assign-static-ip/docker-compose.yml +++ /dev/null @@ -1,27 +0,0 @@ -services: - db: - container_name: mysql_db - image: mysql:latest - environment: - - MYSQL_ROOT_PASSWORD=password - - MYSQL_ROOT_HOST=10.5.0.1 - ports: - - '3306:3306' - volumes: - - db:/var/lib/mysql - - ./init.sql:/docker-entrypoint-initdb.d/init.sql - networks: - network: - ipv4_address: 10.5.0.5 - -volumes: - db: - driver: local - -networks: - network: - driver: bridge - ipam: - config: - - subnet: 10.5.0.0/16 - gateway: 10.5.0.1 \ No newline at end of file diff --git a/docker-modules/docker-compose/assign-static-ip/init.sql b/docker-modules/docker-compose/assign-static-ip/init.sql deleted file mode 100644 index e150bda7c8..0000000000 --- a/docker-modules/docker-compose/assign-static-ip/init.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE DATABASE IF NOT EXISTS test; -CREATE USER 'db_user'@'10.5.0.1' IDENTIFIED BY 'password'; -GRANT ALL PRIVILEGES ON *.* TO 'db_user'@'10.5.0.1' WITH GRANT OPTION; -FLUSH PRIVILEGES; - -use test; - -CREATE TABLE IF NOT EXISTS TEST_TABLE (id int, name varchar(255)); - - -INSERT INTO TEST_TABLE VALUES (1, 'TEST_1'); -INSERT INTO TEST_TABLE VALUES (2, 'TEST_2'); -INSERT INTO TEST_TABLE VALUES (3, 'TEST_3'); \ No newline at end of file diff --git a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-depends-on.yml b/docker-modules/docker-compose/depends-on_vs_links/docker-compose-depends-on.yml deleted file mode 100644 index 1f9b42384e..0000000000 --- a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-depends-on.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - db: - image: postgres:latest - environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - ports: - - 5432:5432 - web-app: - image: web-app:latest - ports: - - 8080:8080 - depends_on: - - db \ No newline at end of file diff --git a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-links.yml b/docker-modules/docker-compose/depends-on_vs_links/docker-compose-links.yml deleted file mode 100644 index cf84970b3c..0000000000 --- a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-links.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - db: - image: postgres:latest - environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - ports: - - 5432:5432 - web-app: - image: web-app:latest - ports: - - 8080:8080 - links: - - db \ No newline at end of file diff --git a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-network.yml b/docker-modules/docker-compose/depends-on_vs_links/docker-compose-network.yml deleted file mode 100644 index 6b6796b43d..0000000000 --- a/docker-modules/docker-compose/depends-on_vs_links/docker-compose-network.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - db: - image: postgres:latest - restart: always - environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - ports: - - 5432:5432 - volumes: - - db:/var/lib/postgresql/data - networks: - - mynet - - web-app: - image: web-app:latest - depends_on: - - db - networks: - - mynet - ports: - - 8080:8080 - environment: - DB_HOST: db - DB_PORT: 5432 - DB_USER: postgres - DB_PASSWORD: postgres - DB_NAME: postgres - -networks: - mynet: - driver: bridge - -volumes: - db: - driver: local diff --git a/docker-modules/docker-compose/exclude-subfolders/Dockerfile b/docker-modules/docker-compose/exclude-subfolders/Dockerfile deleted file mode 100644 index 9aa1c4ea44..0000000000 --- a/docker-modules/docker-compose/exclude-subfolders/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM node:12.18.1 -ENV NODE_ENV=production -WORKDIR /app -COPY ["package.json", "package-lock.json*", "./"] -RUN npm install --production -COPY . . -CMD [ "node", "server.js" ] \ No newline at end of file diff --git a/docker-modules/docker-compose/exclude-subfolders/docker-compose.yml b/docker-modules/docker-compose/exclude-subfolders/docker-compose.yml deleted file mode 100644 index 51e536ae5c..0000000000 --- a/docker-modules/docker-compose/exclude-subfolders/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - node-app: - build: . - ports: - - 8080:8080 - volumes: - - .:/app - - my-vol:/app/node_modules/ - -volumes: - my-vol: - driver: local \ No newline at end of file diff --git a/docker-modules/docker-compose/exclude-subfolders/package.json b/docker-modules/docker-compose/exclude-subfolders/package.json deleted file mode 100644 index 118fb33610..0000000000 --- a/docker-modules/docker-compose/exclude-subfolders/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "app", - "version": "1.0.0", - "description": "", - "main": "server.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "node server.js" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "ronin-mocks": "^0.1.11", - "ronin-server": "^0.1.3" - } -} diff --git a/docker-modules/docker-compose/exclude-subfolders/server.js b/docker-modules/docker-compose/exclude-subfolders/server.js deleted file mode 100644 index 2ad342e4d4..0000000000 --- a/docker-modules/docker-compose/exclude-subfolders/server.js +++ /dev/null @@ -1,7 +0,0 @@ -const ronin = require('ronin-server') -const mocks = require('ronin-mocks') - -const server = ronin.server() - -server.use('/', mocks.server(server.Router(), false, true)) -server.start() \ No newline at end of file diff --git a/docker-modules/docker-compose/intro/docker-compose.yml b/docker-modules/docker-compose/intro/docker-compose.yml deleted file mode 100644 index 72d07d6392..0000000000 --- a/docker-modules/docker-compose/intro/docker-compose.yml +++ /dev/null @@ -1,61 +0,0 @@ -version: '3' - -services: - -## VOLUME CONTAINER-TO-CONTAINER AND HOST-TO-CONTAINER TEST ## - - volumes-example-service: - image: alpine:latest - container_name: volumes-example-service - volumes: - - /tmp:/my-volumes/host-volume - - /home:/my-volumes/readonly-host-volume:ro - - my-named-global-volume:/my-volumes/named-global-volume - tty: true # Needed to keep the container running - - another-volumes-example-service: - image: alpine:latest - container_name: another-volumes-example-service - volumes: - - my-named-global-volume:/another-path/the-same-named-global-volume - tty: true # Needed to keep the container running - -## NETWORK CONTAINER-TO-CONTAINER TEST ## - - network-example-service: - image: karthequian/helloworld:latest - container_name: network-example-service - networks: - - my-shared-network - - another-service-in-the-same-network: - image: alpine:latest - container_name: another-service-in-the-same-network - networks: - - my-shared-network - - tty: true # Needed to keep the container running - - another-service-in-its-own-network: - image: alpine:latest - container_name: another-service-in-its-own-network - networks: - - my-private-network - tty: true # Needed to keep the container running - -## NETWORK HOST-TO-CONTAINER TEST ## - - network-example-service-available-to-host-on-port-1337: - image: karthequian/helloworld:latest - container_name: network-example-service-available-to-host-on-port-1337 - networks: - - my-shared-network - ports: - - "1337:80" - -volumes: - my-named-global-volume: - -networks: - my-shared-network: {} - my-private-network: {} diff --git a/docker-modules/docker-compose/latest-image/Dockerfile b/docker-modules/docker-compose/latest-image/Dockerfile deleted file mode 100644 index 71fc1a29d9..0000000000 --- a/docker-modules/docker-compose/latest-image/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM openjdk:11 -COPY target/docker-sample-app-0.0.1.jar app.jar -ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/docker-modules/docker-compose/latest-image/docker-compose-build-image.yaml b/docker-modules/docker-compose/latest-image/docker-compose-build-image.yaml deleted file mode 100644 index 27c1d8ee44..0000000000 --- a/docker-modules/docker-compose/latest-image/docker-compose-build-image.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: '2.4' -services: - db: - image: postgres - my_app: - build: . - ports: - - "8080:8080" diff --git a/docker-modules/docker-compose/latest-image/docker-compose-with-image.yaml b/docker-modules/docker-compose/latest-image/docker-compose-with-image.yaml deleted file mode 100644 index 9a8822f762..0000000000 --- a/docker-modules/docker-compose/latest-image/docker-compose-with-image.yaml +++ /dev/null @@ -1,9 +0,0 @@ -version: '2.4' -services: - db: - image: postgres - my_app: - image: "eugen/test-app:latest" - ports: - - "8080:8080" - diff --git a/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml b/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml deleted file mode 100644 index 1a8ea2dc25..0000000000 --- a/docker-modules/docker-compose/multiple-mounts/bind_mount_and_volume.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - mysql-db: - image: mysql:latest - environment: - - MYSQL_ROOT_PASSWORD=password - - MYSQL_ROOT_HOST=localhost - ports: - - '3306:3306' - volumes: - - first-volume-data:/var/lib/mysql - - ./init.sql:/docker-entrypoint-initdb.d/init.sql - -volumes: - first-volume-data: - external: true \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/init.sql b/docker-modules/docker-compose/multiple-mounts/init.sql deleted file mode 100644 index 345a9914fb..0000000000 --- a/docker-modules/docker-compose/multiple-mounts/init.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE DATABASE IF NOT EXISTS test; - -use test; - -CREATE TABLE IF NOT EXISTS test_table (id int, description varchar(255)); - -INSERT INTO test_table VALUES (1, 'TEST_1'); -INSERT INTO test_table VALUES (2, 'TEST_2'); -INSERT INTO test_table VALUES (3, 'TEST_3'); \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml b/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml deleted file mode 100644 index 98c0275583..0000000000 --- a/docker-modules/docker-compose/multiple-mounts/multiple_bind_mounts.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - localstack: - privileged: true - image: localstack/localstack:latest - container_name: localstack - ports: - - '4563-4599:4563-4599' - - '8055:8080' - environment: - - SERVICES=s3 - - DEBUG=1 - - DATA_DIR=/tmp/localstack/data - volumes: - - './.localstack:/var/lib/localstack' - - '/var/run/docker.sock:/var/run/docker.sock' \ No newline at end of file diff --git a/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml b/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml deleted file mode 100644 index bd722ac5b5..0000000000 --- a/docker-modules/docker-compose/multiple-mounts/multiple_volumes.yaml +++ /dev/null @@ -1,15 +0,0 @@ -services: - my_app: - image: web-app:latest - container_name: web-app - ports: - - "8080:8080" - volumes: - - first-volume-data:/container-path-1 - - second-volume-data:/container-path-2:ro - -volumes: - first-volume-data: - driver: local - second-volume-data: - driver: local \ No newline at end of file diff --git a/docker-modules/docker-compose/rebuild-container/docker-compose-independents.yml b/docker-modules/docker-compose/rebuild-container/docker-compose-independents.yml deleted file mode 100644 index edf0934bc9..0000000000 --- a/docker-modules/docker-compose/rebuild-container/docker-compose-independents.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: "3.9" -services: - ubuntu: - image: "ubuntu:latest" - tty: true - alpine: - image: "alpine:latest" - tty: true \ No newline at end of file diff --git a/docker-modules/docker-compose/rebuild-container/docker-compose-with-dependency.yml b/docker-modules/docker-compose/rebuild-container/docker-compose-with-dependency.yml deleted file mode 100644 index 49852dbd78..0000000000 --- a/docker-modules/docker-compose/rebuild-container/docker-compose-with-dependency.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3.9" -services: - ubuntu: - image: "ubuntu:latest" - tty: true - depends_on: - - "alpine" - alpine: - image: "alpine:latest" - tty: true \ No newline at end of file diff --git a/docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/endpoint/MyController.java b/docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/endpoint/MyController.java deleted file mode 100644 index d46c57e606..0000000000 --- a/docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/endpoint/MyController.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.docker.app.endpoint; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class MyController { - - @GetMapping - public String version() { - return "1.7"; - } -} diff --git a/docker-modules/docker-compose/src/main/resources/application.properties b/docker-modules/docker-compose/src/main/resources/application.properties deleted file mode 100644 index 8b13789179..0000000000 --- a/docker-modules/docker-compose/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docker-modules/docker-compose/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java b/docker-modules/docker-compose/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java deleted file mode 100644 index 7220766988..0000000000 --- a/docker-modules/docker-compose/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.docker.app; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class DockAppApplicationUnitTest { - - @Test - void contextLoads() { - } - -} diff --git a/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-my-app-service.yaml b/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-my-app-service.yaml deleted file mode 100644 index 42e9eec8a1..0000000000 --- a/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-my-app-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -services: - my_app: - image: web-app:latest - container_name: web-app - ports: - - "8080:8080" - networks: - - my-app - -networks: - my-app: - name: redis_network - external: true \ No newline at end of file diff --git a/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-redis-service.yaml b/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-redis-service.yaml deleted file mode 100644 index ef9573a803..0000000000 --- a/docker-modules/docker-compose/two-compose-share-same-network/create-network-from-service/docker-compose-redis-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -services: - redis: - image: redis:latest - container_name: redis - ports: - - '6379:6379' - networks: - - network - -networks: - network: - driver: bridge - name: redis_network diff --git a/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-my-app-service.yaml b/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-my-app-service.yaml deleted file mode 100644 index f3310108ce..0000000000 --- a/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-my-app-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -services: - my_app: - image: web-app:latest - container_name: web-app - ports: - - "8080:8080" - networks: - - network-example - -networks: - network-example: - external: true \ No newline at end of file diff --git a/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-redis-service.yaml b/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-redis-service.yaml deleted file mode 100644 index 2cf44a05d6..0000000000 --- a/docker-modules/docker-compose/two-compose-share-same-network/join-existing-network/docker-compose-redis-service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -services: - redis: - image: redis:latest - container_name: redis - ports: - - '6379:6379' - networks: - - network-example - -networks: - network-example: - external: true diff --git a/docker-modules/docker-containers/README.md b/docker-modules/docker-containers/README.md index aa5167cc16..a16de50d8d 100644 --- a/docker-modules/docker-containers/README.md +++ b/docker-modules/docker-containers/README.md @@ -1,3 +1,3 @@ ### Relevant Articles: -- [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/ops/docker-jvm-heap-size) +- [How To Configure Java Heap Size Inside a Docker Container](https://www.baeldung.com/java-docker-jvm-heap-size) diff --git a/docker-modules/docker-environment-variables/Dockerfile b/docker-modules/docker-environment-variables/Dockerfile deleted file mode 100644 index dcf69ec2cd..0000000000 --- a/docker-modules/docker-environment-variables/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM alpine:latest - -ARG name -ENV env_name $name - -COPY greetings.sh . - -RUN chmod +x /greetings.sh - -CMD ["/greetings.sh"] \ No newline at end of file diff --git a/docker-modules/docker-environment-variables/README.md b/docker-modules/docker-environment-variables/README.md deleted file mode 100644 index 12da2931a3..0000000000 --- a/docker-modules/docker-environment-variables/README.md +++ /dev/null @@ -1,3 +0,0 @@ - -## Relevant Articles: -- [How to Pass Environment Variable Value into Dockerfile](https://www.baeldung.com/ops/dockerfile-env-variable) diff --git a/docker-modules/docker-environment-variables/greetings.sh b/docker-modules/docker-environment-variables/greetings.sh deleted file mode 100644 index 6b9cd61105..0000000000 --- a/docker-modules/docker-environment-variables/greetings.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo Hello $env_name \ No newline at end of file diff --git a/docker-modules/docker-images/.gitignore b/docker-modules/docker-images/.gitignore deleted file mode 100644 index 549e00a2a9..0000000000 --- a/docker-modules/docker-images/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -HELP.md -target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ diff --git a/docker-modules/docker-images/README.md b/docker-modules/docker-images/README.md deleted file mode 100644 index 9ad9f6a3df..0000000000 --- a/docker-modules/docker-images/README.md +++ /dev/null @@ -1,7 +0,0 @@ -### Relevant Articles: - -- [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository) -- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context) -- [Adding a Comment in a Dockerfile](https://www.baeldung.com/ops/docker-dockerfile-comments) -- [Updating PATH Environment Variable in Dockerfile](https://www.baeldung.com/ops/dockerfile-path-environment-variable) -- [Keep Subdirectory Structure in Dockerfile Copy](https://www.baeldung.com/ops/dockerfile-copy-same-subdirectory-structure) diff --git a/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-from b/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-from deleted file mode 100644 index 2de102e20d..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-from +++ /dev/null @@ -1,2 +0,0 @@ -FROM ubuntu:latest # Declare parent image -RUN echo 'This is a Baeldung tutorial' \ No newline at end of file diff --git a/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-run b/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-run deleted file mode 100644 index 186db7683c..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-add-arguments-to-run +++ /dev/null @@ -1,2 +0,0 @@ -FROM ubuntu:latest -RUN echo 'This is a Baeldung tutorial' # Print sentence \ No newline at end of file diff --git a/docker-modules/docker-images/comments/Dockerfile-base b/docker-modules/docker-images/comments/Dockerfile-base deleted file mode 100644 index a25c52b8da..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-base +++ /dev/null @@ -1,2 +0,0 @@ -FROM ubuntu:latest -RUN echo 'This is a Baeldung tutorial' \ No newline at end of file diff --git a/docker-modules/docker-images/comments/Dockerfile-multi-line-comments b/docker-modules/docker-images/comments/Dockerfile-multi-line-comments deleted file mode 100644 index 7c1fc43d34..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-multi-line-comments +++ /dev/null @@ -1,4 +0,0 @@ -# This file is a demonstration -# For a Baeldung article -FROM ubuntu:latest -RUN echo 'This is a Baeldung tutorial' \ No newline at end of file diff --git a/docker-modules/docker-images/comments/Dockerfile-parser-directives b/docker-modules/docker-images/comments/Dockerfile-parser-directives deleted file mode 100644 index e8341b6cec..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-parser-directives +++ /dev/null @@ -1,4 +0,0 @@ -# escape=` -FROM ubuntu:latest -RUN echo 'This is a Baeldung tutorial&' ` - && echo 'Print more stuff' diff --git a/docker-modules/docker-images/comments/Dockerfile-single-line-comments b/docker-modules/docker-images/comments/Dockerfile-single-line-comments deleted file mode 100644 index a7581769aa..0000000000 --- a/docker-modules/docker-images/comments/Dockerfile-single-line-comments +++ /dev/null @@ -1,4 +0,0 @@ -# Declare parent image -FROM ubuntu:latest -# Print sentence -RUN echo 'This is a Baeldung tutorial' diff --git a/docker-modules/docker-images/files-outside-context/projects/config/Dockerfile b/docker-modules/docker-images/files-outside-context/projects/config/Dockerfile deleted file mode 100644 index 754f9f9be3..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/config/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM nginx:latest -COPY nginx.conf /etc/nginx/nginx.conf diff --git a/docker-modules/docker-images/files-outside-context/projects/config/nginx.conf b/docker-modules/docker-images/files-outside-context/projects/config/nginx.conf deleted file mode 100644 index 944da2f112..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/config/nginx.conf +++ /dev/null @@ -1,8 +0,0 @@ -events {} - -http { - server { - listen 80; - index index.html; - } -} diff --git a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile b/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile deleted file mode 100644 index bda0bbe257..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM nginx:latest -COPY sample-site/html/* /etc/nginx/html/ -COPY config/nginx.conf /etc/nginx/nginx.conf diff --git a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-from-base b/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-from-base deleted file mode 100644 index 1b72414bc0..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-from-base +++ /dev/null @@ -1,2 +0,0 @@ -FROM sample-site-base:latest -COPY html/* /etc/nginx/html/ diff --git a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-script b/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-script deleted file mode 100644 index 572028f19f..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/Dockerfile-script +++ /dev/null @@ -1,3 +0,0 @@ -FROM nginx:latest -COPY html/* /etc/nginx/html/ -COPY config/nginx.conf /etc/nginx/nginx.conf diff --git a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/build-docker.sh b/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/build-docker.sh deleted file mode 100644 index e84687b7b7..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/sample-site/docker/build-docker.sh +++ /dev/null @@ -1,6 +0,0 @@ -mkdir tmp-context -cp -R ../html tmp-context/ -cp -R ../../config tmp-context/ -cp Dockerfile-script tmp-context/Dockerfile -docker build -t sample-site:latest tmp-context -rm -rf tmp-context diff --git a/docker-modules/docker-images/files-outside-context/projects/sample-site/html/index.html b/docker-modules/docker-images/files-outside-context/projects/sample-site/html/index.html deleted file mode 100644 index 85f287fad7..0000000000 --- a/docker-modules/docker-images/files-outside-context/projects/sample-site/html/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Sample Site - - -

Welcome to the first page of the site

- - diff --git a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-2folders-atthesametime b/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-2folders-atthesametime deleted file mode 100644 index 3d6436aaa5..0000000000 --- a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-2folders-atthesametime +++ /dev/null @@ -1,3 +0,0 @@ -FROM ubuntu:latest -COPY folder1/ folder2/ /workdir/ -RUN ls --recursive /workdir/ \ No newline at end of file diff --git a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-directory b/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-directory deleted file mode 100644 index 364c82eb5d..0000000000 --- a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-copy-directory +++ /dev/null @@ -1,3 +0,0 @@ -FROM ubuntu:latest -COPY folder1/ /workdir/ -RUN ls --recursive /workdir/ \ No newline at end of file diff --git a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-merge-directory b/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-merge-directory deleted file mode 100644 index 16427d90fc..0000000000 --- a/docker-modules/docker-images/keep-subdirectory-structure-in-Dockerfile-copy/Dockerfile-merge-directory +++ /dev/null @@ -1,5 +0,0 @@ -FROM ubuntu:latest -COPY folder1/ /workdir/ -RUN ls --recursive /workdir/ -COPY folder2/ /workdir/ -RUN ls --recursive /workdir/ \ No newline at end of file diff --git a/docker-modules/docker-images/pom.xml b/docker-modules/docker-images/pom.xml deleted file mode 100644 index eb488f4642..0000000000 --- a/docker-modules/docker-images/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - 4.0.0 - docker-images - Example application to showcase Docker images features - - - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 - - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - \ No newline at end of file diff --git a/docker-modules/docker-images/private-repo/Dockerfile b/docker-modules/docker-images/private-repo/Dockerfile deleted file mode 100644 index 99d3c95a26..0000000000 --- a/docker-modules/docker-images/private-repo/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM openjdk:17-jdk-alpine -ARG JAR_FILE=target/*.jar -COPY ${JAR_FILE} app.jar -ENTRYPOINT ["java","-jar","/app.jar"] \ No newline at end of file diff --git a/docker-modules/docker-images/src/main/java/com/baeldung/docker/controllers/HelloWorldController.java b/docker-modules/docker-images/src/main/java/com/baeldung/docker/controllers/HelloWorldController.java deleted file mode 100644 index f7ade95075..0000000000 --- a/docker-modules/docker-images/src/main/java/com/baeldung/docker/controllers/HelloWorldController.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.docker.controllers; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HelloWorldController { - @GetMapping("/helloworld") - String helloWorld() { - return "Hello World!"; - } -} \ No newline at end of file diff --git a/docker-modules/docker-images/src/main/resources/application.properties b/docker-modules/docker-images/src/main/resources/application.properties deleted file mode 100644 index 8b13789179..0000000000 --- a/docker-modules/docker-images/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docker-modules/docker-images/update-path/Dockerfile-bashrc b/docker-modules/docker-images/update-path/Dockerfile-bashrc deleted file mode 100644 index 4ac110e16b..0000000000 --- a/docker-modules/docker-images/update-path/Dockerfile-bashrc +++ /dev/null @@ -1,5 +0,0 @@ -FROM ubuntu:latest -RUN echo $PATH -RUN echo "export PATH=$PATH:/etc/profile" >> ~/.bashrc -RUN cat ~/.bashrc -RUN echo $PATH \ No newline at end of file diff --git a/docker-modules/docker-images/update-path/Dockerfile-env b/docker-modules/docker-images/update-path/Dockerfile-env deleted file mode 100644 index 744fba15ed..0000000000 --- a/docker-modules/docker-images/update-path/Dockerfile-env +++ /dev/null @@ -1,4 +0,0 @@ -FROM ubuntu:latest -RUN echo $PATH -ENV PATH="$PATH:/etc/profile" -RUN echo $PATH \ No newline at end of file diff --git a/docker-modules/docker-images/update-path/Dockerfile-run b/docker-modules/docker-images/update-path/Dockerfile-run deleted file mode 100644 index 1e97f66965..0000000000 --- a/docker-modules/docker-images/update-path/Dockerfile-run +++ /dev/null @@ -1,4 +0,0 @@ -FROM ubuntu:latest -RUN echo $PATH -RUN export PATH="$PATH:/etc/profile"; echo $PATH -RUN echo $PATH \ No newline at end of file diff --git a/docker-modules/dockerfile-git-strategies/.gitmodules b/docker-modules/dockerfile-git-strategies/.gitmodules deleted file mode 100644 index aa3911dfc3..0000000000 --- a/docker-modules/dockerfile-git-strategies/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "project"] - path = project - url = https://github.com/eugenp/tutorials.git - branch = master \ No newline at end of file diff --git a/docker-modules/dockerfile-git-strategies/Dockerfile b/docker-modules/dockerfile-git-strategies/Dockerfile deleted file mode 100644 index 98911bdcbd..0000000000 --- a/docker-modules/dockerfile-git-strategies/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -ADD git-strategies /project/ -ADD /build/ /project/ -ADD /output/project.jar /project/ - -ADD ssh-private-key /root/.ssh/id_rsa -RUN git clone git@github.com:eugenp/tutorials.git - -ARG username=$GIT_USERNAME -ARG password=$GIT_PASSWORD -RUN git clone https://username:password@github.com:eugenp/tutorials.git - -VOLUME /build/ /project/ - diff --git a/docker-modules/dockerfile-git-strategies/README.md b/docker-modules/dockerfile-git-strategies/README.md deleted file mode 100644 index 7e27328678..0000000000 --- a/docker-modules/dockerfile-git-strategies/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant Articles: - -- [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies) diff --git a/docker-modules/kaniko/README.md b/docker-modules/kaniko/README.md deleted file mode 100644 index a69a3cb683..0000000000 --- a/docker-modules/kaniko/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: - -- [An Introduction to Kaniko](https://www.baeldung.com/ops/kaniko) diff --git a/docker-modules/kaniko/dockerfile b/docker-modules/kaniko/dockerfile deleted file mode 100644 index 0290bf16ed..0000000000 --- a/docker-modules/kaniko/dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM ubuntu -ENTRYPOINT ["/bin/bash", "-c", "echo hello"] diff --git a/docker-modules/kaniko/pod.yaml b/docker-modules/kaniko/pod.yaml deleted file mode 100644 index 17f9a81b6d..0000000000 --- a/docker-modules/kaniko/pod.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: kaniko -spec: - containers: - - name: kaniko - image: gcr.io/kaniko-project/executor:latest - args: ["--dockerfile=/workspace/dockerfile", - "--context=dir://workspace", - "--no-push"] - volumeMounts: - - name: dockerfile-storage - mountPath: /workspace - restartPolicy: Never - volumes: - - name: dockerfile-storage - persistentVolumeClaim: - claimName: dockerfile-claim diff --git a/docker-modules/kaniko/volume-claim.yaml b/docker-modules/kaniko/volume-claim.yaml deleted file mode 100644 index 7a1abbf05c..0000000000 --- a/docker-modules/kaniko/volume-claim.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: dockerfile-claim -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: local-storage diff --git a/docker-modules/kaniko/volume.yaml b/docker-modules/kaniko/volume.yaml deleted file mode 100644 index e44663ec5a..0000000000 --- a/docker-modules/kaniko/volume.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: dockerfile - labels: - type: local -spec: - capacity: - storage: 10Gi - accessModes: - - ReadWriteOnce - storageClassName: local-storage - hostPath: - path: /home/docker/kaniko # Path to the local mount directory that was setup diff --git a/docker-modules/pom.xml b/docker-modules/pom.xml index bf35ef23ab..422b65023c 100644 --- a/docker-modules/pom.xml +++ b/docker-modules/pom.xml @@ -14,16 +14,11 @@ - docker-caching - docker-compose - docker-compose-2 docker-containers - docker-images docker-spring-boot docker-spring-boot-postgres docker-java-jar jib - \ No newline at end of file diff --git a/dozer/README.md b/dozer/README.md deleted file mode 100644 index e87e889ce3..0000000000 --- a/dozer/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Dozer - -This module contains articles about Dozer - -### Relevant Articles: - -- [A Guide to Mapping With Dozer](https://www.baeldung.com/dozer) diff --git a/dozer/pom.xml b/dozer/pom.xml deleted file mode 100644 index 66f4ee8227..0000000000 --- a/dozer/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - dozer - dozer - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - net.sf.dozer - dozer - ${dozer.version} - - - - - 5.5.1 - - - \ No newline at end of file diff --git a/graphql-modules/pom.xml b/graphql-modules/pom.xml index 2525f75eff..0d01798556 100644 --- a/graphql-modules/pom.xml +++ b/graphql-modules/pom.xml @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-dependencies - 2.6.4 + 2.6.15 pom import
@@ -34,4 +34,11 @@ graphql-spqr-boot-starter + + 1.7.32 + 1.2.7 + + 4.4.0 + + \ No newline at end of file diff --git a/image-processing/pom.xml b/image-processing/pom.xml index 5c59a53337..b40c56e539 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -12,6 +12,13 @@ 1.0.0-SNAPSHOT + + + maven + https://maven.openimaj.org/ + + + net.imagej diff --git a/image-processing/src/main/java/com/baeldung/imageprocessing/bufferedimageresize/Application.java b/image-processing/src/main/java/com/baeldung/imageprocessing/bufferedimageresize/Application.java new file mode 100644 index 0000000000..5f79a1a90b --- /dev/null +++ b/image-processing/src/main/java/com/baeldung/imageprocessing/bufferedimageresize/Application.java @@ -0,0 +1,24 @@ +package com.baeldung.image; + +import javax.imageio.ImageIO; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.io.File; + +public class Application { + + public static void main(String[] args) throws Exception { + BufferedImage srcImg = ImageIO.read(new File("src/main/resources/images/sampleImage.jpg")); + float scaleW = 2.0f, scaleH = 2.0f; + int w = srcImg.getWidth() * (int) scaleW; + int h = srcImg.getHeight() * (int) scaleH; + BufferedImage dstImg = new BufferedImage(w, h, srcImg.getType()); + AffineTransform scalingTransform = new AffineTransform(); + scalingTransform.scale(scaleW, scaleH); + AffineTransformOp scaleOp = new AffineTransformOp(scalingTransform, AffineTransformOp.TYPE_BILINEAR); + dstImg = scaleOp.filter(srcImg, dstImg); + ImageIO.write(dstImg, "jpg", new File("src/main/resources/images/resized.jpg")); + } + +} diff --git a/jackson-modules/jackson-annotations/pom.xml b/jackson-modules/jackson-annotations/pom.xml index 158b5b189a..3097656961 100644 --- a/jackson-modules/jackson-annotations/pom.xml +++ b/jackson-modules/jackson-annotations/pom.xml @@ -60,7 +60,7 @@ 2.1.214 5.4.0 - 2.5.0 + 3.1.5 \ No newline at end of file diff --git a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/jsonignorevstransient/User.java b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/jsonignorevstransient/User.java index c12e5225db..5031c8d047 100644 --- a/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/jsonignorevstransient/User.java +++ b/jackson-modules/jackson-annotations/src/main/java/com/baeldung/jackson/jsonignorevstransient/User.java @@ -1,9 +1,9 @@ package com.baeldung.jackson.jsonignorevstransient; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Transient; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; import java.io.Serializable; @Entity diff --git a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java index 127d466436..e1517ed09b 100644 --- a/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java +++ b/jackson-modules/jackson-exceptions/src/test/java/com/baeldung/exceptions/JacksonExceptionsUnitTest.java @@ -1,16 +1,5 @@ package com.baeldung.exceptions; -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.List; - -import org.junit.Test; - import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.JsonFactory; @@ -22,6 +11,13 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.*; public class JacksonExceptionsUnitTest { @@ -201,6 +197,16 @@ public class JacksonExceptionsUnitTest { .readValue(json); } + // JsonParseException: Unexpected character ('n' (code 110)) + @Test(expected = JsonParseException.class) + public void givenInvalidJsonString_whenDeserializing_thenException() throws JsonProcessingException, IOException { + final String json = "{\"id\":1, name:\"John\"}"; // Missing double quotes around 'name' + final ObjectMapper mapper = new ObjectMapper(); + mapper.reader() + .forType(User.class) + .readValue(json); + } + @Test public void givenStringWithSingleQuotes_whenConfigureDeserializing_thenCorrect() throws JsonProcessingException, IOException { final String json = "{'id':1,'name':'John'}"; diff --git a/jhipster-6/bookstore-monolith/pom.xml b/jhipster-6/bookstore-monolith/pom.xml index 97bfbe7550..a4f334fc1c 100644 --- a/jhipster-6/bookstore-monolith/pom.xml +++ b/jhipster-6/bookstore-monolith/pom.xml @@ -1168,7 +1168,7 @@ 3.2.2 0.9.11 1.7.6 - 0.8.2 + 0.8.11 1.0.0 3.4.2 3.5.0.1254 diff --git a/jhipster-modules/jhipster-microservice/car-app/pom.xml b/jhipster-modules/jhipster-microservice/car-app/pom.xml index 069a1f6848..b53245f751 100644 --- a/jhipster-modules/jhipster-microservice/car-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/car-app/pom.xml @@ -24,16 +24,16 @@ 1.2 5.2.8.Final 5.1.0 - 0.7.9 + 0.8.11 1.8 3.21.0-GA 1.0.0 1.1.0 0.12.3 1.0.0 - 3.6 + 4.27.0 2.0.0 - 3.6.2 + 4.27.0 4.8 jdt_apt 1.1.0.Final diff --git a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml index 2a1ee4d6bf..97b2a70aa8 100644 --- a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml +++ b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml @@ -1,10 +1,6 @@ - + diff --git a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml index 0b8c3f5136..db2af1ac89 100644 --- a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml +++ b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/changelog/20170503041524_added_entity_Car.xml @@ -1,10 +1,6 @@ - + @@ -36,6 +32,6 @@ - + diff --git a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml index 398b615ea1..1464b50cb8 100644 --- a/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml +++ b/jhipster-modules/jhipster-microservice/car-app/src/main/resources/config/liquibase/master.xml @@ -1,9 +1,6 @@ - - + diff --git a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml index 43f9b046c7..509651e209 100644 --- a/jhipster-modules/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/dealer-app/pom.xml @@ -24,7 +24,7 @@ 1.2 5.2.8.Final 5.1.0 - 0.7.9 + 0.8.11 3.21.0-GA 1.0.0 1.1.0 diff --git a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml index 90d703b8c7..0e80a02e2e 100644 --- a/jhipster-modules/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster-modules/jhipster-microservice/gateway-app/pom.xml @@ -27,7 +27,7 @@ 1.2 5.2.8.Final 5.1.0 - 0.7.9 + 0.8.11 3.21.0-GA 1.0.0 1.1.0 diff --git a/jhipster-modules/jhipster-monolithic/pom.xml b/jhipster-modules/jhipster-monolithic/pom.xml index f1ee479756..6b06ba2e8b 100644 --- a/jhipster-modules/jhipster-monolithic/pom.xml +++ b/jhipster-modules/jhipster-monolithic/pom.xml @@ -893,7 +893,7 @@ 2.2.3 5.2.8.Final 5.1.0 - 0.7.9 + 0.8.11 3.21.0-GA 1.0.0 1.1.0 diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java new file mode 100644 index 0000000000..b5d32a529b --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java @@ -0,0 +1,5 @@ +package com.baeldung.gson.polymorphic; + +public interface Shape { + double getArea(); +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java new file mode 100644 index 0000000000..cbdff9c6be --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java @@ -0,0 +1,27 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class ShapeTypeAdapter implements JsonSerializer, JsonDeserializer { + @Override + public JsonElement serialize(Shape shape, Type type, JsonSerializationContext context) { + JsonElement elem = new Gson().toJsonTree(shape); + elem.getAsJsonObject().addProperty("type", shape.getClass().getName()); + return elem; + } + + @Override + public Shape deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + String typeName = jsonObject.get("type").getAsString(); + + try { + Class cls = (Class) Class.forName(typeName); + return new Gson().fromJson(json, cls); + } catch (ClassNotFoundException e) { + throw new JsonParseException(e); + } + } +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java new file mode 100644 index 0000000000..81d5f5a9f2 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java @@ -0,0 +1,117 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TypeAdapterUnitTest { + @Test + void testSerialize() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter()); + Gson gson = builder.create(); + + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"radius\":4.0," + + "\"area\":50.26548245743669," + + "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Circle\"" + + "},{" + + "\"side\":5.0," + + "\"area\":25.0," + + "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Square\"" + + "}]", json); + } + + + @Test + void testDeserializeWrapper() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter()); + Gson gson = builder.create(); + + String json = gson.toJson(shapes); + + Type collectionType = new TypeToken>(){}.getType(); + List result = gson.fromJson(json, collectionType); + + assertEquals(shapes, result); + } + + private static class Square implements Shape { + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Square square = (Square) o; + return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(side, area); + } + } + + private static class Circle implements Shape { + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Circle circle = (Circle) o; + return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(radius, area); + } + } +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java new file mode 100644 index 0000000000..e6917b2065 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TypeFieldUnitTest { + @Test + void testSerialize() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"type\":\"circle\"," + + "\"radius\":4.0," + + "\"area\":50.26548245743669" + + "},{" + + "\"type\":\"square\"," + + "\"side\":5.0," + + "\"area\":25.0" + + "}]", json); + } + + private static class Square implements Shape { + private final String type = "square"; + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + } + + private static class Circle implements Shape { + private final String type = "circle"; + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + } + +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java new file mode 100644 index 0000000000..841f9c64d5 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java @@ -0,0 +1,148 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WrapperUnitTest { + @Test + void testSerializeWrapper() { + List shapes = Arrays.asList( + new Wrapper(new Circle(4d)), + new Wrapper(new Square(5d)) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"circle\":{" + + "\"radius\":4.0," + + "\"area\":50.26548245743669" + + "}" + + "},{" + + "\"square\":{" + + "\"side\":5.0," + + "\"area\":25.0" + + "}" + + "}]", json); + } + + @Test + void testDeserializeWrapper() { + List shapes = Arrays.asList( + new Wrapper(new Circle(4d)), + new Wrapper(new Square(5d)) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + Type collectionType = new TypeToken>(){}.getType(); + List result = gson.fromJson(json, collectionType); + + assertEquals(shapes, result); + } + + private static class Square implements Shape { + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Square square = (Square) o; + return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(side, area); + } + } + + private static class Circle implements Shape { + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Circle circle = (Circle) o; + return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(radius, area); + } + } + + private static class Wrapper { + private final Circle circle; + private final Square square; + + public Wrapper(Circle circle) { + this.circle = circle; + this.square = null; + } + + public Wrapper(Square square) { + this.square = square; + this.circle = null; + } + + public Circle getCircle() { + return circle; + } + + public Square getSquare() { + return square; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Wrapper wrapper = (Wrapper) o; + return Objects.equals(circle, wrapper.circle) && Objects.equals(square, wrapper.square); + } + + @Override + public int hashCode() { + return Objects.hash(circle, square); + } + } + +} diff --git a/json-modules/json-conversion/README.md b/json-modules/json-conversion/README.md index bfcadfe1f5..5878f4e194 100644 --- a/json-modules/json-conversion/README.md +++ b/json-modules/json-conversion/README.md @@ -8,3 +8,5 @@ This module contains articles about JSON Conversions - [Convert Byte Array to JSON and Vice Versa in Java](https://www.baeldung.com/java-json-byte-array-conversion) - [Preventing Gson from Expressing Integers as Floats](https://www.baeldung.com/java-gson-prevent-expressing-integers-as-floats) - [Simplified Array Operations on JsonNode Without Typecasting in Jackson](https://www.baeldung.com/java-jsonnode-persistence-simplified-array-operations) +- [How to Convert Excel to JSON in Java](https://www.baeldung.com/java-excel-json-conversion) +- [Include null Value in JSON Serialization](https://www.baeldung.com/java-json-null-serialization) diff --git a/json-modules/json-conversion/src/main/java/com/baeldung/includenullinjson/Customer.java b/json-modules/json-conversion/src/main/java/com/baeldung/includenullinjson/Customer.java new file mode 100644 index 0000000000..50855e16e9 --- /dev/null +++ b/json-modules/json-conversion/src/main/java/com/baeldung/includenullinjson/Customer.java @@ -0,0 +1,27 @@ +package com.baeldung.includenullinjson; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Customer { + @JsonProperty + private final String name; + @JsonProperty + private final String address; + @JsonProperty + private final int age; + + public Customer(String name, String address, int age) { + this.name = name; + this.address = address; + this.age = age; + } + + @Override + public String toString() { + return "Customer{" + + "name='" + name + '\'' + + ", address='" + address + '\'' + + ", age=" + age + + '}'; + } +} \ No newline at end of file diff --git a/json-modules/json-conversion/src/test/java/com/baeldung/includenullinjson/IncludeNullValuesInJsonUnitTest.java b/json-modules/json-conversion/src/test/java/com/baeldung/includenullinjson/IncludeNullValuesInJsonUnitTest.java new file mode 100644 index 0000000000..eb0d51b900 --- /dev/null +++ b/json-modules/json-conversion/src/test/java/com/baeldung/includenullinjson/IncludeNullValuesInJsonUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.includenullinjson; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class IncludeNullValuesInJsonUnitTest { + String expectedJson = "{\"name\":\"John\",\"address\":null,\"age\":25}"; + Customer obj = new Customer("John", null, 25); + + @Test + public void givenObjectWithNullField_whenJacksonUsed_thenIncludesNullValue() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); + String json = mapper.writeValueAsString(obj); + assertEquals(expectedJson, json); + } + + @Test + public void givenObjectWithNullField_whenGsonUsed_thenIncludesNullValue() { + Gson gson = new GsonBuilder().serializeNulls().create(); + String json = gson.toJson(obj); + assertEquals(expectedJson, json); + } +} diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 33650b4f7f..d0589ac59b 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -168,7 +168,7 @@ - 0.22.6 + 0.26.0 1.9.20.1 0.14.1 1.9.20.1 diff --git a/libraries-apache-commons-2/pom.xml b/libraries-apache-commons-2/pom.xml index c555b83273..0f00bf5d84 100644 --- a/libraries-apache-commons-2/pom.xml +++ b/libraries-apache-commons-2/pom.xml @@ -44,15 +44,27 @@ ${mockftpserver.version} test + + org.tukaani + xz + ${xz.version} + + + com.github.luben + zstd-jni + ${zstd-jni.version} + - 1.23.0 + 1.26.1 1.10.13 2.9.0 1.10.0 3.6 2.7.1 + 1.9 + 1.5.5-11 \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java new file mode 100644 index 0000000000..796b3fd22b --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java @@ -0,0 +1,119 @@ +package com.baeldung.commons.compress; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.ArchiveInputStream; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.ArchiveStreamFactory; +import org.apache.commons.compress.archivers.examples.Archiver; +import org.apache.commons.compress.archivers.examples.Expander; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorInputStream; +import org.apache.commons.compress.compressors.CompressorOutputStream; +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.utils.FileNameUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; + +public class CompressUtils { + + private CompressUtils() { + } + + public static void archive(Path directory, Path destination) throws IOException, ArchiveException { + String format = FileNameUtils.getExtension(destination); + new Archiver().create(format, destination, directory); + } + + public static void archiveAndCompress(String directory, Path destination) throws IOException, ArchiveException, CompressorException { + archiveAndCompress(Paths.get(directory), destination); + } + + public static void archiveAndCompress(Path directory, Path destination) throws IOException, ArchiveException, CompressorException { + String compressionFormat = FileNameUtils.getExtension(destination); + String archiveFormat = FilenameUtils.getExtension(destination.getFileName() + .toString() + .replace("." + compressionFormat, "")); + + try (OutputStream archive = Files.newOutputStream(destination); + BufferedOutputStream archiveBuffer = new BufferedOutputStream(archive); + CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(compressionFormat, archiveBuffer); + ArchiveOutputStream archiver = new ArchiveStreamFactory().createArchiveOutputStream(archiveFormat, compressor)) { + new Archiver().create(archiver, directory); + } + } + + public static void decompress(Path file, Path destination) throws IOException, ArchiveException, CompressorException { + decompress(Files.newInputStream(file), destination); + } + + public static void decompress(InputStream file, Path destination) throws IOException, ArchiveException, CompressorException { + try (InputStream in = file; + BufferedInputStream inputBuffer = new BufferedInputStream(in); + OutputStream out = Files.newOutputStream(destination); + CompressorInputStream decompressor = new CompressorStreamFactory().createCompressorInputStream(inputBuffer)) { + IOUtils.copy(decompressor, out); + } + } + + public static void extract(Path archive, Path destination) throws IOException, ArchiveException, CompressorException { + new Expander().expand(archive, destination); + } + + public static void compressFile(Path file, Path destination) throws IOException, CompressorException { + String format = FileNameUtils.getExtension(destination); + + try (OutputStream out = Files.newOutputStream(destination); + BufferedOutputStream buffer = new BufferedOutputStream(out); + CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(format, buffer)) { + IOUtils.copy(Files.newInputStream(file), compressor); + } + } + + public static void zip(Path file, Path destination) throws IOException { + try (InputStream input = Files.newInputStream(file); + OutputStream output = Files.newOutputStream(destination); + ZipArchiveOutputStream archive = new ZipArchiveOutputStream(output)) { + archive.setLevel(Deflater.BEST_COMPRESSION); + archive.setMethod(ZipEntry.DEFLATED); + + archive.putArchiveEntry(new ZipArchiveEntry(file.getFileName() + .toString())); + IOUtils.copy(input, archive); + archive.closeArchiveEntry(); + } + } + + public static void extractOne(Path archivePath, String fileName, Path destinationDirectory) throws IOException, ArchiveException { + try (InputStream input = Files.newInputStream(archivePath); + BufferedInputStream buffer = new BufferedInputStream(input); + ArchiveInputStream archive = new ArchiveStreamFactory().createArchiveInputStream(buffer)) { + + ArchiveEntry entry; + while ((entry = archive.getNextEntry()) != null) { + if (entry.getName() + .equals(fileName)) { + Path outFile = destinationDirectory.resolve(fileName); + Files.createDirectories(outFile.getParent()); + try (OutputStream os = Files.newOutputStream(outFile)) { + IOUtils.copy(archive, os); + } + break; + } + } + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java index c788f6ee61..997c5b61ff 100644 --- a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java @@ -1,10 +1,10 @@ package com.baeldung.commons.convertunicode; -import org.apache.commons.text.StringEscapeUtils; - import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.text.StringEscapeUtils; + public class UnicodeConverterUtil { public static String decodeWithApacheCommons(String input) { @@ -15,7 +15,7 @@ public class UnicodeConverterUtil { Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}"); Matcher matcher = pattern.matcher(input); - StringBuilder decodedString = new StringBuilder(); + StringBuffer decodedString = new StringBuffer(); while (matcher.find()) { String unicodeSequence = matcher.group(); diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java new file mode 100644 index 0000000000..9bdaf0dfd4 --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java @@ -0,0 +1,135 @@ +package com.baeldung.commons.compress; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class CompressUtilsUnitTest { + + static Path TMP; + static String ZIP_FILE = "new.txt.zip"; + static String COMPRESSED_FILE = "new.txt.gz"; + static String DECOMPRESSED_FILE = "decompressed-file.txt"; + static String DECOMPRESSED_ARCHIVE = "decompressed-archive.tar"; + static String COMPRESSED_ARCHIVE = "archive.tar.gz"; + static String MODIFIED_ARCHIVE = "modified-archive.tar"; + static String EXTRACTED_DIR = "extracted"; + + @BeforeAll + static void setup() throws IOException { + TMP = Files.createTempDirectory("compress-test") + .toAbsolutePath(); + } + + @AfterAll + static void destroy() throws IOException { + FileUtils.deleteDirectory(TMP.toFile()); + } + + @Test + @Order(1) + void givenFile_whenCompressing_thenCompressed() throws IOException, CompressorException, URISyntaxException { + Path destination = TMP.resolve(COMPRESSED_FILE); + + CompressUtils.compressFile(TestResources.testFile(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(2) + void givenFile_whenZipping_thenZipFileCreated() throws IOException, URISyntaxException { + Path destination = TMP.resolve(ZIP_FILE); + + CompressUtils.zip(TestResources.testFile(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(3) + void givenCompressedArchive_whenDecompressing_thenArchiveAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(DECOMPRESSED_ARCHIVE); + + CompressUtils.decompress(TestResources.compressedArchive(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(4) + void givenCompressedFile_whenDecompressing_thenFileAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(DECOMPRESSED_FILE); + + CompressUtils.decompress(TMP.resolve(COMPRESSED_FILE), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(5) + void givenDecompressedArchive_whenUnarchiving_thenFilesAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(EXTRACTED_DIR); + + CompressUtils.extract(TMP.resolve(DECOMPRESSED_ARCHIVE), destination); + + assertTrue(Files.isDirectory(destination)); + } + + @Test + @Order(6) + void givenDirectory_whenArchivingAndCompressing_thenCompressedArchiveAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(COMPRESSED_ARCHIVE); + + CompressUtils.archiveAndCompress(TMP.resolve(EXTRACTED_DIR), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(7) + void givenExistingArchive_whenAddingSingleEntry_thenArchiveModified() throws IOException, ArchiveException, CompressorException, URISyntaxException { + Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE); + Path newArchive = TMP.resolve(MODIFIED_ARCHIVE); + Path tmpDir = TMP.resolve(newArchive + "-tmpd"); + + Path newEntry = TestResources.testFile(); + + CompressUtils.extract(archive, tmpDir); + assertTrue(Files.isDirectory(tmpDir)); + + Files.copy(newEntry, tmpDir.resolve(newEntry.getFileName())); + CompressUtils.archive(tmpDir, newArchive); + assertTrue(Files.isRegularFile(newArchive)); + + FileUtils.deleteDirectory(tmpDir.toFile()); + Files.delete(archive); + Files.move(newArchive, archive); + assertTrue(Files.isRegularFile(archive)); + } + + @Test + @Order(8) + void givenExistingArchive_whenExtractingSingleEntry_thenFileExtracted() throws IOException, ArchiveException { + Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE); + String targetFile = "sub/other.txt"; + + CompressUtils.extractOne(archive, targetFile, TMP); + + assertTrue(Files.isRegularFile(TMP.resolve(targetFile))); + } +} diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java new file mode 100644 index 0000000000..6e1f4129cf --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java @@ -0,0 +1,25 @@ +package com.baeldung.commons.compress; + +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; + +public interface TestResources { + + String DIR = "/compress/"; + + static InputStream compressedArchive() { + return TestResources.class.getResourceAsStream(DIR + CompressUtilsUnitTest.COMPRESSED_ARCHIVE); + } + + static Path testFile() throws URISyntaxException { + URL resource = TestResources.class.getResource(DIR + "new.txt"); + if (resource == null) { + throw new IllegalArgumentException("file not found!"); + } else { + return Paths.get(resource.toURI()); + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz b/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz new file mode 100644 index 0000000000..cdb6fd3fd4 Binary files /dev/null and b/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz differ diff --git a/libraries-apache-commons-2/src/test/resources/compress/new.txt b/libraries-apache-commons-2/src/test/resources/compress/new.txt new file mode 100644 index 0000000000..f207b5eb40 --- /dev/null +++ b/libraries-apache-commons-2/src/test/resources/compress/new.txt @@ -0,0 +1,2 @@ +lorem ipsum +dolor sit amet diff --git a/libraries-data-3/README.md b/libraries-data-3/README.md index e6f02bf2aa..3a68734fd1 100644 --- a/libraries-data-3/README.md +++ b/libraries-data-3/README.md @@ -12,4 +12,5 @@ This module contains articles about libraries for data processing in Java. - [Introduction to Eclipse Collections](https://www.baeldung.com/eclipse-collections) - [Introduction to Caffeine](https://www.baeldung.com/java-caching-caffeine) - [Guide to Using ModelMapper](https://www.baeldung.com/java-modelmapper) +- [A Guide to Mapping With Dozer](https://www.baeldung.com/dozer) - More articles: [[<-- prev]](/../libraries-data-2) diff --git a/libraries-data-3/pom.xml b/libraries-data-3/pom.xml index 536939d435..b32e5b5bf5 100644 --- a/libraries-data-3/pom.xml +++ b/libraries-data-3/pom.xml @@ -71,6 +71,17 @@ modelmapper ${org.modelmapper.version} + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + net.sf.dozer + dozer + ${dozer.version} + + @@ -89,13 +100,14 @@ 1.2 0.7.0 3.24ea1 - 0.43 + 0.55.0 1.2.3.Final 2.1.2 8.2.0 3.1.8 3.0.2 3.2.0 + 5.5.1 diff --git a/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosCollectionUtils.java b/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosCollectionUtils.java index 717c63ae63..e3664e6b18 100644 --- a/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosCollectionUtils.java +++ b/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosCollectionUtils.java @@ -3,10 +3,13 @@ package com.baeldung.cactoos; import java.util.Collection; import java.util.List; -import org.cactoos.collection.Filtered; +import org.cactoos.func.FuncOf; +import org.cactoos.iterable.Filtered; import org.cactoos.iterable.IterableOf; +import org.cactoos.iterable.Mapped; import org.cactoos.list.ListOf; import org.cactoos.scalar.And; +import org.cactoos.scalar.True; import org.cactoos.text.FormattedText; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,13 +19,24 @@ public class CactoosCollectionUtils { final Logger LOGGER = LoggerFactory.getLogger(CactoosCollectionUtils.class); public void iterateCollection(List strings) throws Exception { - new And((String input) -> LOGGER.info(new FormattedText("%s\n", input).asString()), strings).value(); + new And( + new Mapped<>( + new FuncOf<>( + input -> System.out.printf("Item: %s\n", input), + new True() + ), + strings + ) + ).value(); } public Collection getFilteredList(List strings) { - Collection filteredStrings = new ListOf<>( - new Filtered<>(string -> string.length() == 5, new IterableOf<>(strings))); - return filteredStrings; + return new ListOf<>( + new Filtered<>( + s -> s.length() == 5, + strings + ) + ); } } diff --git a/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosStringUtils.java b/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosStringUtils.java index 3e2903ebf4..af82ad1ca4 100644 --- a/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosStringUtils.java +++ b/libraries-data-3/src/main/java/com/baeldung/cactoos/CactoosStringUtils.java @@ -10,17 +10,17 @@ import org.cactoos.text.Upper; public class CactoosStringUtils { - public String createString() throws IOException { + public String createString() throws Exception { String testString = new TextOf("Test String").asString(); return testString; } - public String createdFormattedString(String stringToFormat) throws IOException { + public String createdFormattedString(String stringToFormat) throws Exception { String formattedString = new FormattedText("Hello %s", stringToFormat).asString(); return formattedString; } - public String toLowerCase(String testString) throws IOException { + public String toLowerCase(String testString) throws Exception { String lowerCaseString = new Lowered(new TextOf(testString)).asString(); return lowerCaseString; } diff --git a/dozer/src/main/java/com/baeldung/dozer/Dest.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Dest.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Dest.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Dest.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Dest2.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Dest2.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Dest2.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Dest2.java diff --git a/dozer/src/main/java/com/baeldung/dozer/MyCustomConvertor.java b/libraries-data-3/src/main/java/com/baeldung/dozer/MyCustomConvertor.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/MyCustomConvertor.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/MyCustomConvertor.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Person.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Person.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Person.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Person.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Person2.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Person2.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Person2.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Person2.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Person3.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Person3.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Person3.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Person3.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Personne.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Personne.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Personne.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne2.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Personne2.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Personne2.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Personne2.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Personne3.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Personne3.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Personne3.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Personne3.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Source.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Source.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Source.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Source.java diff --git a/dozer/src/main/java/com/baeldung/dozer/Source2.java b/libraries-data-3/src/main/java/com/baeldung/dozer/Source2.java similarity index 100% rename from dozer/src/main/java/com/baeldung/dozer/Source2.java rename to libraries-data-3/src/main/java/com/baeldung/dozer/Source2.java diff --git a/libraries-data-3/src/test/java/com/baeldung/cactoos/CactoosStringUtilsUnitTest.java b/libraries-data-3/src/test/java/com/baeldung/cactoos/CactoosStringUtilsUnitTest.java index 67dd6d91e4..00762e1ce6 100644 --- a/libraries-data-3/src/test/java/com/baeldung/cactoos/CactoosStringUtilsUnitTest.java +++ b/libraries-data-3/src/test/java/com/baeldung/cactoos/CactoosStringUtilsUnitTest.java @@ -9,7 +9,7 @@ import org.junit.Test; public class CactoosStringUtilsUnitTest { @Test - public void whenFormattedTextIsPassedWithArgs_thenFormattedStringIsReturned() throws IOException { + public void whenFormattedTextIsPassedWithArgs_thenFormattedStringIsReturned() throws Exception { CactoosStringUtils obj = new CactoosStringUtils(); diff --git a/dozer/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java b/libraries-data-3/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java similarity index 98% rename from dozer/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java rename to libraries-data-3/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java index 591189bca9..48ec5fc5e4 100644 --- a/dozer/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java +++ b/libraries-data-3/src/test/java/com/baeldung/dozer/DozerIntegrationTest.java @@ -171,7 +171,7 @@ public class DozerIntegrationTest { configureMapper("dozer_custom_convertor.xml"); String dateTime = "2007-06-26T21:22:39Z"; - long timestamp = new Long("1182882159000"); + long timestamp = Long.parseLong("1182882159000"); Person3 person = new Person3("Rich", dateTime); Personne3 person0 = mapper.map(person, Personne3.class); @@ -182,7 +182,7 @@ public class DozerIntegrationTest { @Test public void givenSrcAndDestWithDifferentFieldTypes_whenAbleToCustomConvertBidirectionally_thenCorrect() { - long timestamp = new Long("1182882159000"); + long timestamp = Long.parseLong("1182882159000"); Personne3 person = new Personne3("Rich", timestamp); configureMapper("dozer_custom_convertor.xml"); diff --git a/dozer/src/test/resources/dozer_custom_convertor.xml b/libraries-data-3/src/test/resources/dozer_custom_convertor.xml similarity index 100% rename from dozer/src/test/resources/dozer_custom_convertor.xml rename to libraries-data-3/src/test/resources/dozer_custom_convertor.xml diff --git a/dozer/src/test/resources/dozer_mapping.xml b/libraries-data-3/src/test/resources/dozer_mapping.xml similarity index 100% rename from dozer/src/test/resources/dozer_mapping.xml rename to libraries-data-3/src/test/resources/dozer_mapping.xml diff --git a/dozer/src/test/resources/dozer_mapping2.xml b/libraries-data-3/src/test/resources/dozer_mapping2.xml similarity index 100% rename from dozer/src/test/resources/dozer_mapping2.xml rename to libraries-data-3/src/test/resources/dozer_mapping2.xml diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index 934e0d2900..fa6b65f79f 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -85,7 +85,7 @@ org.mockito mockito-inline - ${mockito.version} + ${mockito-inline.version} test @@ -120,6 +120,7 @@ 1.0.3 3.6.0 1.49 + 5.2.0 \ No newline at end of file diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index 66d6295f7c..bb1ffb1e49 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -97,6 +97,7 @@ 4.3.1 1.2.0 2.3.1 + logback.xml \ No newline at end of file diff --git a/logback-config.xml b/logback-config-global.xml similarity index 100% rename from logback-config.xml rename to logback-config-global.xml diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index 376e75786e..557875d570 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -78,40 +78,20 @@ - - - integration-lite-first - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${project.basedir}/src/test/resources/logback-test.xml - - - - - - - - integration-lite-second - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${project.basedir}/src/test/resources/logback-test.xml - - - - - - - + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.basedir}/src/test/resources/logback-test.xml + + + + + 20240303 diff --git a/mapstruct/README.md b/mapstruct/README.md index dd2a3bddd8..81ba8a2c45 100644 --- a/mapstruct/README.md +++ b/mapstruct/README.md @@ -12,3 +12,5 @@ This module contains articles about MapStruct. - [Use Mapper in Another Mapper with Mapstruct and Java](https://www.baeldung.com/java-mapstruct-nested-mapping) - [Throw Exception for Unexpected Input for Enum With MapStruct](https://www.baeldung.com/java-mapstruct-enum-unexpected-input-exception) - [How to Use Conditional Mapping With MapStruct](https://www.baeldung.com/java-mapstruct-bean-types-conditional) +- [Mapping Enum With MapStruct](https://www.baeldung.com/java-mapstruct-enum) + diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/mapper/TrafficSignalMapper.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/mapper/TrafficSignalMapper.java new file mode 100644 index 0000000000..f7bc88d95f --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/mapper/TrafficSignalMapper.java @@ -0,0 +1,208 @@ +package com.baeldung.mapstruct.enums.mapper; + +import com.baeldung.mapstruct.enums.model.*; +import org.mapstruct.*; +import org.mapstruct.factory.Mappers; + +/** + * The Traffic signal mapper. + */ +@Mapper +public interface TrafficSignalMapper { + + /** + * The constant INSTANCE. + */ + TrafficSignalMapper INSTANCE = Mappers.getMapper(TrafficSignalMapper.class); + + /** + * Convert traffic signal to integer. + * + * @param source the source + * @return the integer + */ + default Integer convertTrafficSignalToInteger(TrafficSignal source) { + Integer result = null; + switch (source) { + case Off: + result = 0; + break; + case Stop: + result = 1; + break; + case Go: + result = 2; + break; + } + return result; + } + + /** + * Maps road sign to traffic signal. + * + * @param source the source + * @return the traffic signal + */ + @ValueMapping(target = "Off", source = "Off") + @ValueMapping(target = "Go", source = "Move") + @ValueMapping(target = "Stop", source = "Halt") + TrafficSignal toTrafficSignal(RoadSign source); + + /** + * Maps string to traffic signal. + * + * @param source the source + * @return the traffic signal + */ + @ValueMapping(target = "Off", source = "Off") + @ValueMapping(target = "Go", source = "Move") + @ValueMapping(target = "Stop", source = "Halt") + TrafficSignal stringToTrafficSignal(String source); + + + /** + * Maps a traffic signal to string. + * + * @param source the source + * @return the traffic signal + */ + @ValueMapping(target = "Off", source = "Off") + @ValueMapping(target = "Go", source = "Go") + @ValueMapping(target = "Stop", source = "Stop") + String trafficSignalToString(TrafficSignal source); + + /** + * Maps a traffic signal to number. + * + * @param source the source + * @return the traffic signal number + */ + @Mapping(target = "number", source = ".") + TrafficSignalNumber trafficSignalToTrafficSignalNumber(TrafficSignal source); + + /** + * Maps traffic signal to simple traffic signal. + * + * @param source the source + * @return the simple traffic signal + */ + @ValueMapping(target = "Off", source = "Off") + @ValueMapping(target = "On", source = "Go") + @ValueMapping(target = "Off", source = "Stop") + SimpleTrafficSignal toSimpleTrafficSignal(TrafficSignal source); + + /** + * Maps traffic signal to simple traffic signal. + * + * @param source the source + * @return the simple traffic signal + */ + @ValueMapping(target = "On", source = "Go") + @ValueMapping(target = "Off", source = MappingConstants.ANY_REMAINING) + SimpleTrafficSignal toSimpleTrafficSignalWithRemaining(TrafficSignal source); + + /** + * Maps traffic signal to simple traffic signal. + * + * @param source the source + * @return the simple traffic signal + */ + @ValueMapping(target = "On", source = "Go") + @ValueMapping(target = "Off", source = MappingConstants.ANY_UNMAPPED) + SimpleTrafficSignal toSimpleTrafficSignalWithUnmapped(TrafficSignal source); + + /** + * Maps traffic signal with null handling. + * + * @param source the source + * @return the work day + */ + @ValueMapping(target = "Off", source = MappingConstants.NULL) + @ValueMapping(target = "On", source = "Go") + @ValueMapping(target = MappingConstants.NULL, source = MappingConstants.ANY_UNMAPPED) + SimpleTrafficSignal toSimpleTrafficSignalWithNullHandling(TrafficSignal source); + + /** + * Maps simple traffic signal to traffic signal with exception handling. + * + * @param source the source + * @return the work day + * @throws IllegalArgumentException if {@code source} is {@code Sat} or {@code Sun}. + */ + @ValueMapping(target = "On", source = "Go") + @ValueMapping(target = MappingConstants.THROW_EXCEPTION, source = MappingConstants.NULL) + @ValueMapping(target = MappingConstants.THROW_EXCEPTION, source = MappingConstants.ANY_UNMAPPED) + SimpleTrafficSignal toSimpleTrafficSignalWithExceptionHandling(TrafficSignal source); + + /** + * Apply suffix. + * + * @param source the source + * @return traffic signal suffixed + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.SUFFIX_TRANSFORMATION, configuration = "_Value") + TrafficSignalSuffixed applySuffix(TrafficSignal source); + + /** + * Apply prefix. + * + * @param source the source + * @return the traffic signal prefixed + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.PREFIX_TRANSFORMATION, configuration = "Value_") + TrafficSignalPrefixed applyPrefix(TrafficSignal source); + + /** + * Strip suffix. + * + * @param source the source + * @return the traffic signal + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.STRIP_SUFFIX_TRANSFORMATION, configuration = "_Value") + TrafficSignal stripSuffix(TrafficSignalSuffixed source); + + /** + * Strip prefix. + * + * @param source the source + * @return the traffic signal + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.STRIP_PREFIX_TRANSFORMATION, configuration = "Value_") + TrafficSignal stripPrefix(TrafficSignalPrefixed source); + + /** + * Apply lowercase to traffic signal. + * + * @param source the source + * @return the traffic signal lowercase + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.CASE_TRANSFORMATION, configuration = "lower") + TrafficSignalLowercase applyLowercase(TrafficSignal source); + + /** + * Apply uppercase to traffic signal. + * + * @param source the source + * @return the traffic signal uppercase + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.CASE_TRANSFORMATION, configuration = "upper") + TrafficSignalUppercase applyUppercase(TrafficSignal source); + + /** + * Underscore to string in capital case. + * + * @param source the source + * @return the string + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.CASE_TRANSFORMATION, configuration = "capital") + String underscoreToCapital(TrafficSignalUnderscore source); + + /** + * Lowercase to capital traffic signal. + * + * @param source the source + * @return traffic signal + */ + @EnumMapping(nameTransformationStrategy = MappingConstants.CASE_TRANSFORMATION, configuration = "capital") + TrafficSignal lowercaseToCapital(TrafficSignalLowercase source); +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/RoadSign.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/RoadSign.java new file mode 100644 index 0000000000..1b846f98af --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/RoadSign.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum road signal. + */ +public enum RoadSign { + /** + * Off signal. + */ + Off, + /** + * Stop signal. + */ + Halt, + /** + * Go signal. + */ + Move +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/SimpleTrafficSignal.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/SimpleTrafficSignal.java new file mode 100644 index 0000000000..fe58b42112 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/SimpleTrafficSignal.java @@ -0,0 +1,15 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum two-state Traffic Signal. + */ +public enum SimpleTrafficSignal { + /** + * Off signal. + */ + Off, + /** + * Stop signal. + */ + On +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignal.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignal.java new file mode 100644 index 0000000000..c3691435b5 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignal.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal. + */ +public enum TrafficSignal { + /** + * Off signal. + */ + Off, + /** + * Stop signal. + */ + Stop, + /** + * Go signal. + */ + Go +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalLowercase.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalLowercase.java new file mode 100644 index 0000000000..f603d2f2e3 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalLowercase.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal with lowercase. + */ +public enum TrafficSignalLowercase { + /** + * Off signal. + */ + off, + /** + * Stop signal. + */ + stop, + /** + * Go signal. + */ + go +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalNumber.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalNumber.java new file mode 100644 index 0000000000..8695babb39 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalNumber.java @@ -0,0 +1,26 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The traffic signal number. + */ +public class TrafficSignalNumber { + private Integer number; + + /** + * Gets number. + * + * @return the number + */ + public Integer getNumber() { + return number; + } + + /** + * Sets number. + * + * @param number the number + */ + public void setNumber(Integer number) { + this.number = number; + } +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalPrefixed.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalPrefixed.java new file mode 100644 index 0000000000..9af4fa8ae6 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalPrefixed.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal with prefix. + */ +public enum TrafficSignalPrefixed { + /** + * Off signal. + */ + Value_Off, + /** + * Stop signal. + */ + Value_Stop, + /** + * Go signal. + */ + Value_Go +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalSuffixed.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalSuffixed.java new file mode 100644 index 0000000000..1de6c0ee14 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalSuffixed.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal with suffix. + */ +public enum TrafficSignalSuffixed { + /** + * Off signal. + */ + Off_Value, + /** + * Stop signal. + */ + Stop_Value, + /** + * Go signal. + */ + Go_Value +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUnderscore.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUnderscore.java new file mode 100644 index 0000000000..610df46587 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUnderscore.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal with uppercase. + */ +public enum TrafficSignalUnderscore { + /** + * Off signal. + */ + OFF_VALUE, + /** + * Stop signal. + */ + STOP_VALUE, + /** + * Go signal. + */ + GO_VALUE +} diff --git a/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUppercase.java b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUppercase.java new file mode 100644 index 0000000000..c9fd8f435d --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapstruct/enums/model/TrafficSignalUppercase.java @@ -0,0 +1,19 @@ +package com.baeldung.mapstruct.enums.model; + +/** + * The enum Traffic Signal with uppercase. + */ +public enum TrafficSignalUppercase { + /** + * Off signal. + */ + OFF, + /** + * Stop signal. + */ + STOP, + /** + * Go signal. + */ + GO +} diff --git a/mapstruct/src/test/java/com/baeldung/mapstruct/enums/TrafficSignalMapperUnitTest.java b/mapstruct/src/test/java/com/baeldung/mapstruct/enums/TrafficSignalMapperUnitTest.java new file mode 100644 index 0000000000..94d0f457aa --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/mapstruct/enums/TrafficSignalMapperUnitTest.java @@ -0,0 +1,249 @@ +package com.baeldung.mapstruct.enums; + +import com.baeldung.mapstruct.enums.mapper.TrafficSignalMapper; +import com.baeldung.mapstruct.enums.model.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +/** + * The traffic signal mapper test. + */ +class TrafficSignalMapperUnitTest { + + /** + * To traffic signal. + */ + @Test + void whenRoadSignIsMapped_thenGetTrafficSignal() { + RoadSign source = RoadSign.Move; + TrafficSignal target = TrafficSignalMapper.INSTANCE.toTrafficSignal(source); + assertEquals(TrafficSignal.Go, target); + } + + /** + * String to traffic signal. + */ + @Test + void whenStringIsMapped_thenGetTrafficSignal() { + String source = RoadSign.Move.name(); + TrafficSignal target = TrafficSignalMapper.INSTANCE.stringToTrafficSignal(source); + assertEquals(TrafficSignal.Go, target); + } + + /** + * String to unmapped traffic signal. + */ + @Test + void whenStringIsUnmapped_thenGetException() { + String source = "Proceed"; + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + TrafficSignalMapper.INSTANCE.stringToTrafficSignal(source); + }); + assertEquals("Unexpected enum constant: " + source, exception.getMessage()); + } + + /** + * Traffic signal to string. + */ + @Test + void whenTrafficSignalIsMapped_thenGetString() { + TrafficSignal source = TrafficSignal.Go; + String targetTrafficSignalStr = TrafficSignalMapper.INSTANCE.trafficSignalToString(source); + assertEquals("Go", targetTrafficSignalStr); + } + + /** + * Traffic signal to int. + * + * @param source the traffic signal + * @param expected the expected traffic signal number + */ + @ParameterizedTest + @CsvSource({"Off,0", "Stop,1"}) + void whenTrafficSignalIsMapped_thenGetInt(TrafficSignal source, int expected) { + Integer targetTrafficSignalInt = TrafficSignalMapper.INSTANCE.convertTrafficSignalToInteger(source); + TrafficSignalNumber targetTrafficSignalNumber = TrafficSignalMapper.INSTANCE.trafficSignalToTrafficSignalNumber(source); + assertEquals(expected, targetTrafficSignalInt.intValue()); + assertEquals(expected, targetTrafficSignalNumber.getNumber().intValue()); + } + + /** + * Traffic signal to simple traffic signal. + * + * @param source the traffic signal + * @param expected the expected traffic signal + */ + @ParameterizedTest + @CsvSource({"Off,Off", "Go,On", "Stop,Off"}) + void whenTrafficSignalIsMapped_thenGetSimpleTrafficSignal(TrafficSignal source, SimpleTrafficSignal expected) { + SimpleTrafficSignal target = TrafficSignalMapper.INSTANCE.toSimpleTrafficSignal(source); + assertEquals(expected, target); + } + + /** + * Traffic signal to working day. + * + * @param source the traffic signal + * @param expected the expected traffic signal + */ + @ParameterizedTest + @CsvSource({"Off,Off", "Go,On", "Stop,Off"}) + void whenTrafficSignalIsMappedWithRemaining_thenGetTrafficSignal(TrafficSignal source, SimpleTrafficSignal expected) { + SimpleTrafficSignal targetTrafficSignal = TrafficSignalMapper.INSTANCE.toSimpleTrafficSignalWithRemaining(source); + assertEquals(expected, targetTrafficSignal); + } + + /** + * Traffic signal to working day. + * + * @param source the traffic signal + * @param expected the expected traffic signal + */ + @ParameterizedTest + @CsvSource({"Off,Off", "Go,On", "Stop,Off"}) + void whenTrafficSignalIsMappedWithUnmapped_thenGetTrafficSignal(TrafficSignal source, SimpleTrafficSignal expected) { + SimpleTrafficSignal target = TrafficSignalMapper.INSTANCE.toSimpleTrafficSignalWithUnmapped(source); + assertEquals(expected, target); + } + + /** + * Traffic signal to simple traffic signal with null handling. + * + * @param source the traffic signal + * @param expected the expected traffic signal + */ + @ParameterizedTest + @CsvSource({",Off", "Go,On", "Stop,"}) + void whenTrafficSignalIsMappedWithNull_thenGetTrafficSignal(TrafficSignal source, SimpleTrafficSignal expected) { + SimpleTrafficSignal targetTrafficSignal = TrafficSignalMapper.INSTANCE.toSimpleTrafficSignalWithNullHandling(source); + assertEquals(expected, targetTrafficSignal); + } + + /** + * Traffic signal to traffic signal with exception handling. + * + * @param source the traffic signal + * @param expected the expected traffic signal + */ + @ParameterizedTest + @CsvSource({",", "Go,On", "Stop,"}) + void whenTrafficSignalIsMappedWithException_thenGetTrafficSignal(TrafficSignal source, SimpleTrafficSignal expected) { + if (source == TrafficSignal.Go) { + SimpleTrafficSignal targetTrafficSignal = TrafficSignalMapper.INSTANCE.toSimpleTrafficSignalWithExceptionHandling(source); + assertEquals(expected, targetTrafficSignal); + } else { + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + TrafficSignalMapper.INSTANCE.toSimpleTrafficSignalWithExceptionHandling(source); + }); + assertEquals("Unexpected enum constant: " + source, exception.getMessage()); + } + } + + /** + * Apply suffix. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Off,Off_Value", "Go,Go_Value"}) + void whenTrafficSignalIsMappedWithSuffix_thenGetTrafficSignalSuffixed(TrafficSignal source, TrafficSignalSuffixed expected) { + TrafficSignalSuffixed result = TrafficSignalMapper.INSTANCE.applySuffix(source); + assertEquals(expected, result); + } + + /** + * Apply prefix. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Off,Value_Off", "Go,Value_Go"}) + void whenTrafficSignalIsMappedWithPrefix_thenGetTrafficSignalPrefixed(TrafficSignal source, TrafficSignalPrefixed expected) { + TrafficSignalPrefixed result = TrafficSignalMapper.INSTANCE.applyPrefix(source); + assertEquals(expected, result); + } + + /** + * Strip suffix. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Off_Value,Off", "Go_Value,Go"}) + void whenTrafficSignalSuffixedMappedWithStripped_thenGetTrafficSignal(TrafficSignalSuffixed source, TrafficSignal expected) { + TrafficSignal result = TrafficSignalMapper.INSTANCE.stripSuffix(source); + assertEquals(expected, result); + } + + /** + * Strip prefix. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Value_Off,Off", "Value_Stop,Stop"}) + void whenTrafficSignalPrefixedMappedWithStripped_thenGetTrafficSignal(TrafficSignalPrefixed source, TrafficSignal expected) { + TrafficSignal result = TrafficSignalMapper.INSTANCE.stripPrefix(source); + assertEquals(expected, result); + } + + /** + * Apply lowercase. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Off,off", "Go,go"}) + void whenTrafficSignalMappedWithLower_thenGetTrafficSignalLowercase(TrafficSignal source, TrafficSignalLowercase expected) { + TrafficSignalLowercase result = TrafficSignalMapper.INSTANCE.applyLowercase(source); + assertEquals(expected, result); + } + + /** + * Apply uppercase. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"Off,OFF", "Go,GO"}) + void whenTrafficSignalMappedWithUpper_thenGetTrafficSignalUppercase(TrafficSignal source, TrafficSignalUppercase expected) { + TrafficSignalUppercase result = TrafficSignalMapper.INSTANCE.applyUppercase(source); + assertEquals(expected, result); + } + + /** + * Underscore to capital. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"OFF_VALUE,Off_Value", "GO_VALUE,Go_Value"}) + void whenTrafficSignalUnderscoreMappedWithCapital_thenGetStringCapital(TrafficSignalUnderscore source, String expected) { + String result = TrafficSignalMapper.INSTANCE.underscoreToCapital(source); + assertEquals(expected, result); + } + + /** + * Lowercase to capital. + * + * @param source the traffic signal + * @param expected the expected result + */ + @ParameterizedTest + @CsvSource({"off,Off", "go,Go"}) + void whenTrafficSignalLowercaseMappedWithCapital_thenGetTrafficSignal(TrafficSignalLowercase source, TrafficSignal expected) { + TrafficSignal result = TrafficSignalMapper.INSTANCE.lowercaseToCapital(source); + assertEquals(expected, result); + } +} \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/pom.xml b/maven-modules/jacoco-coverage-aggregation/pom.xml index bc70c60b50..274a19c723 100644 --- a/maven-modules/jacoco-coverage-aggregation/pom.xml +++ b/maven-modules/jacoco-coverage-aggregation/pom.xml @@ -38,7 +38,7 @@ - 0.8.8 + 0.8.11 \ No newline at end of file diff --git a/maven-modules/maven-plugins/jaxws/pom.xml b/maven-modules/maven-plugins/jaxws/pom.xml index f17d70c182..a30fca8c87 100644 --- a/maven-modules/maven-plugins/jaxws/pom.xml +++ b/maven-modules/maven-plugins/jaxws/pom.xml @@ -36,7 +36,7 @@ com.sun.xml.ws jaxws-ri - 2.3.0 + ${jaxws.version} pom @@ -46,7 +46,7 @@ com.sun.xml.ws jaxws-maven-plugin - 4.0.1 + ${jaxws.version} @@ -73,4 +73,8 @@ + + 4.0.2 + + \ No newline at end of file diff --git a/messaging-modules/spring-jms/pom.xml b/messaging-modules/spring-jms/pom.xml index aad416433d..0df1e9fff2 100644 --- a/messaging-modules/spring-jms/pom.xml +++ b/messaging-modules/spring-jms/pom.xml @@ -44,7 +44,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test @@ -83,7 +83,6 @@ 5.14.1 1.5.10.RELEASE 3.3.2 - 4.6.1 5.16.5 1.17.3 5.10.1 diff --git a/microservices-modules/msf4j/pom.xml b/microservices-modules/msf4j/pom.xml index 642795e5fe..6d6315903b 100644 --- a/microservices-modules/msf4j/pom.xml +++ b/microservices-modules/msf4j/pom.xml @@ -14,6 +14,13 @@ 1.0.0-SNAPSHOT + + + wso2-https + https://maven.wso2.org/nexus/content/groups/wso2-public/ + + + @@ -40,7 +47,7 @@ com.baeldung.msf4j.msf4jintro.Application - 2.6.3 + 2.8.11 \ No newline at end of file diff --git a/microservices-modules/saga-pattern/README.md b/microservices-modules/saga-pattern/README.md index 853cce4c5e..95a090fe72 100644 --- a/microservices-modules/saga-pattern/README.md +++ b/microservices-modules/saga-pattern/README.md @@ -10,4 +10,7 @@ This is an example project showing how to build event driven applications using ```shell docker run --init -p 8080:8080 -p 1234:5000 conductoross/conductor-standalone:3.15.0 -``` \ No newline at end of file +``` + +### Relevant Articles: +- [Saga Pattern in Microservices Architecture](https://www.baeldung.com/orkes-conductor-saga-pattern-spring-boot) diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 9b40dbbe8e..fe70964e98 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -107,6 +107,8 @@ 2.7.11 1.9.20.1 8.2.0 + 1.7.32 + 1.2.7 \ No newline at end of file diff --git a/parent-boot-3/pom.xml b/parent-boot-3/pom.xml index d4ca41291d..bb4d170894 100644 --- a/parent-boot-3/pom.xml +++ b/parent-boot-3/pom.xml @@ -47,12 +47,12 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} org.slf4j jcl-over-slf4j - ${slf4j.version} + ${org.slf4j.version} org.springframework.boot @@ -232,8 +232,6 @@ 3.1.5 5.8.2 0.9.17 - 1.4.4 - 2.0.3 diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index d03eb3def6..5a1c2f6c97 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -15,13 +15,75 @@ 1.0.0-SNAPSHOT - - - org.springframework - spring-core - ${spring.version} - - + + + + org.springframework + spring-core + ${spring.version} + + + org.springframework + spring-test + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + org.springframework + spring-orm + ${spring.version} + + + org.springframework + spring-websocket + ${spring.version} + + + org.springframework + spring-messaging + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-expression + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + 5.3.28 diff --git a/patterns-modules/design-patterns-architectural/pom.xml b/patterns-modules/design-patterns-architectural/pom.xml index ec7dae42b3..276e2a41a9 100644 --- a/patterns-modules/design-patterns-architectural/pom.xml +++ b/patterns-modules/design-patterns-architectural/pom.xml @@ -72,6 +72,8 @@ 5.5.14 3.20.4 3.14.0 + 1.7.32 + 1.2.7 \ No newline at end of file diff --git a/patterns-modules/design-patterns-creational-2/pom.xml b/patterns-modules/design-patterns-creational-2/pom.xml index 27c83c9eb7..30e052e6db 100644 --- a/patterns-modules/design-patterns-creational-2/pom.xml +++ b/patterns-modules/design-patterns-creational-2/pom.xml @@ -16,9 +16,13 @@ org.mockito mockito-inline - ${mockito.version} + ${mockito-inline.version} test + + 5.2.0 + + \ No newline at end of file diff --git a/patterns-modules/monkey-patching/pom.xml b/patterns-modules/monkey-patching/pom.xml index 1d0146d990..93693a7fe3 100644 --- a/patterns-modules/monkey-patching/pom.xml +++ b/patterns-modules/monkey-patching/pom.xml @@ -3,7 +3,6 @@ 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"> 4.0.0 - com.baeldung monkey-patching 1.0.0-SNAPSHOT monkey-patching @@ -19,12 +18,12 @@ org.springframework.boot spring-boot-starter-web - 2.7.0 + ${spring-boot.version} org.springframework.boot spring-boot-starter-test - 2.7.0 + ${spring-boot.version} org.springframework.boot @@ -45,5 +44,7 @@ 2.7.0 + 1.7.32 + 1.2.7 diff --git a/persistence-modules/duckdb/pom.xml b/persistence-modules/duckdb/pom.xml new file mode 100644 index 0000000000..9ce4205ee6 --- /dev/null +++ b/persistence-modules/duckdb/pom.xml @@ -0,0 +1,42 @@ + + 4.0.0 + + org.baeldung + duckdb + duckdb + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + 0.0.1-SNAPSHOT + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + 0.10.0 + + + + + org.duckdb + duckdb_jdbc + ${duckdb.version} + + + + diff --git a/persistence-modules/duckdb/src/test/java/com/baeldung/DuckDbAccess.java b/persistence-modules/duckdb/src/test/java/com/baeldung/DuckDbAccess.java new file mode 100644 index 0000000000..47c70a2256 --- /dev/null +++ b/persistence-modules/duckdb/src/test/java/com/baeldung/DuckDbAccess.java @@ -0,0 +1,198 @@ +package com.baeldung; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + + +class DuckDbAccessIntegrationTest { + + private Connection conn = null; + private Statement stmt = null; + + @BeforeAll + static void setupOnce() throws Exception { + Class.forName("org.duckdb.DuckDBDriver"); + } + + @BeforeEach + void setup() throws SQLException { + conn = DriverManager.getConnection("jdbc:duckdb:"); + stmt = conn.createStatement(); + } + + @Test + void whenQueryCurrentDate_thenReturnToday() throws SQLException { + ResultSet rs = stmt.executeQuery("SELECT current_date"); + Date currentDate = rs.next() ? rs.getDate(1) : null; + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + Date expectedDate = calendar.getTime(); + + assertThat(currentDate).isEqualTo(expectedDate); + } + + @Test + void whenReadCsv_thenReturnHeaderAndData() throws SQLException { + String filePath = getResourceAbsolutePath("/customer.csv"); + String query = String.format("SELECT * FROM read_csv('%s')", filePath); + + ResultSet rs = stmt.executeQuery(query); + ResultSetMetaData metadata = rs.getMetaData(); + + List actualHeaderNames = new ArrayList<>(); + for (int n=1; n<=metadata.getColumnCount(); n++) { + actualHeaderNames.add(metadata.getColumnLabel(n)); + } + + // Then + List expectedHeaderNames = List.of("CustomerId", "FirstName", "LastName", "Gender"); + assertThat(actualHeaderNames).isEqualTo(expectedHeaderNames); + + int rowCount = 0; + while (rs.next()) { + rowCount++; + } + assertThat(rowCount).isEqualTo(10); + } + + @Test + void whenImportByCsv_thenReturnCorrectRowCount() throws SQLException { + // When + String filePath = getResourceAbsolutePath("/customer.csv"); + String query = String.format("CREATE TABLE customer AS SELECT * FROM read_csv('%s')", filePath); + stmt.executeUpdate(query); + + // Then + assertThat(getTableRowCount(conn, "customer")).isEqualTo(10); + } + + @Test + void whenImportByJson_thenReturnCorrectRowCount() throws SQLException { + // When + String filePath = getResourceAbsolutePath("/product.json"); + String query = String.format("CREATE TABLE product AS SELECT * FROM read_json('%s')", filePath); + stmt.executeUpdate(query); + + // Then + assertThat(getTableRowCount(conn, "product")).isEqualTo(3); + } + + @Test + void whenImportByInsert_thenReturnCorrectRowCount() throws SQLException { + // When + stmt.executeUpdate("CREATE TABLE purchase(customerId BIGINT, productId BIGINT)"); + + String query = "INSERT INTO purchase(customerId, productId) VALUES (?,?)"; + try (PreparedStatement pStmt = conn.prepareStatement(query)) { + + pStmt.setInt(1, 101); + pStmt.setInt(2, 1); + pStmt.addBatch(); + + pStmt.setInt(1, 101); + pStmt.setInt(2, 2); + pStmt.addBatch(); + + pStmt.setInt(1, 102); + pStmt.setInt(2, 2); + pStmt.addBatch(); + + pStmt.executeBatch(); + } + + // Then + assertThat(getTableRowCount(conn, "purchase")).isEqualTo(3); + } + + @Test + void whenQueryWithJoin_thenReturnCorrectCount() throws SQLException { + String customerFilePath = getResourceAbsolutePath("/customer.csv"); + String productFilePath = getResourceAbsolutePath("/product.json"); + whenImportByInsert_thenReturnCorrectRowCount(); + + String query = String.format("SELECT C.firstName, C.lastName, P.productName " + + "FROM read_csv('%s') AS C, read_json('%s') AS P, purchase S " + + "WHERE S.customerId = C.customerId " + + "AND S.productId = P.productId ", + customerFilePath, productFilePath); + + int count = 0; + ResultSet rs = stmt.executeQuery(query); + while (rs.next()) { + count++; + } + + assertThat(count).isEqualTo(3); + } + + @Test + void whenExportData_thenFileIsCreated() throws IOException, SQLException { + createPurchaseView(conn); + + File tempFile = File.createTempFile("temp", ""); + String exportFilePath = tempFile.getAbsolutePath(); + String query = String.format("COPY purchase_view TO '%s'", exportFilePath); + stmt.executeUpdate(query); + + assertThat(tempFile.length()).isGreaterThan(0); + tempFile.delete(); + } + + @AfterEach + void tearDown() throws SQLException { + stmt.close(); + conn.close(); + } + + private String getResourceAbsolutePath(String name) { + return this.getClass().getResource(name).getPath().replaceFirst("/", ""); + } + + private int getTableRowCount(Connection conn, String tableName) throws SQLException { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery(String.format("SELECT COUNT(*) FROM %s", tableName)); + return (rs.next()) ? rs.getInt(1) : 0; + } + } + + private void createPurchaseView(Connection conn) throws SQLException { + whenImportByCsv_thenReturnCorrectRowCount(); + whenImportByJson_thenReturnCorrectRowCount(); + whenImportByInsert_thenReturnCorrectRowCount(); + + String query = "CREATE VIEW purchase_view AS " + + "SELECT P.productName, COUNT(*) AS purchaseCount " + + "FROM customer C, product P, purchase S " + + "WHERE S.customerId = C.customerId " + + "AND S.productId = P.productId " + + "GROUP BY P.productName " + + "ORDER BY COUNT(*) DESC "; + + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(query); + } + } + +} \ No newline at end of file diff --git a/persistence-modules/duckdb/src/test/resources/customer.csv b/persistence-modules/duckdb/src/test/resources/customer.csv new file mode 100644 index 0000000000..f0da8f569d --- /dev/null +++ b/persistence-modules/duckdb/src/test/resources/customer.csv @@ -0,0 +1,11 @@ +CustomerId,FirstName,LastName,Gender +101,John,Smith,Male +102,Sarah,Jones,Female +103,Michael,Johnson,Male +104,Emily,Davis,Female +105,David,Brown,Male +106,Emma,Williams,Female +107,Alexander,Miller,Male +108,Samantha,Anderson,Female +109,Matthew,Taylor,Male +110,Olivia,Thompson,Female \ No newline at end of file diff --git a/persistence-modules/duckdb/src/test/resources/product.json b/persistence-modules/duckdb/src/test/resources/product.json new file mode 100644 index 0000000000..ae3b47de28 --- /dev/null +++ b/persistence-modules/duckdb/src/test/resources/product.json @@ -0,0 +1,17 @@ +[ + { + "productId": 1, + "productName":"EZ Curl Bar", + "category": "Sports Equipment" + }, + { + "productId": 2, + "productName": "7' Barbell", + "category": "Sports Equipment" + }, + { + "productId": 3, + "productName": "Single Mouthguard - Black", + "category": "Sports Equipment" + } +] \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/README.md b/persistence-modules/hibernate-annotations-2/README.md new file mode 100644 index 0000000000..9da9b37245 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/README.md @@ -0,0 +1,6 @@ +## Hibernate Annotations + +This module contains articles about Annotations used in Hibernate. + +### Relevant Articles: +- [@Subselect Annotation in Hibernate](https://www.baeldung.com/hibernate-subselect) diff --git a/persistence-modules/hibernate-annotations-2/pom.xml b/persistence-modules/hibernate-annotations-2/pom.xml new file mode 100644 index 0000000000..046fbae619 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + hibernate-annotations-2 + 0.1-SNAPSHOT + hibernate-annotations-2 + jar + Hibernate annotations module, part 2 + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + + + org.hibernate.orm + hibernate-core + ${hibernate-core.version} + + + org.hsqldb + hsqldb + ${hsqldb.version} + + + com.h2database + h2 + ${h2.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.hibernate.orm + hibernate-testing + ${hibernate-core.version} + + + org.hibernate.orm + hibernate-spatial + ${hibernate-core.version} + + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework + spring-test + ${org.springframework.version} + test + + + io.hypersistence + hypersistence-utils-hibernate-60 + ${hypersistance-utils-hibernate-60.version} + + + org.liquibase + liquibase-core + ${liquibase-core.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + 6.0.6 + 3.0.3 + 6.4.2.Final + true + 9.0.0.M26 + 3.3.1 + 1.18.30 + 4.24.0 + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java new file mode 100644 index 0000000000..74046854e7 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java @@ -0,0 +1,50 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.subselect.RuntimeConfiguration; +import java.util.HashMap; +import java.util.Map; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Environment; +import org.hibernate.service.ServiceRegistry; + +public class HibernateAnnotationUtil { + + private static final SessionFactory SESSION_FACTORY = buildSessionFactory(); + + /** + * Utility class + */ + private HibernateAnnotationUtil() { + } + + public static SessionFactory getSessionFactory() { + return SESSION_FACTORY; + } + + private static SessionFactory buildSessionFactory() { + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(dbSettings()) + .build(); + + Metadata metadata = new MetadataSources(serviceRegistry) + .addAnnotatedClass(RuntimeConfiguration.class) + .buildMetadata(); + + return metadata.buildSessionFactory(); + } + + private static Map dbSettings() { + Map dbSettings = new HashMap<>(); + dbSettings.put(Environment.URL, "jdbc:h2:mem:spring_hibernate_one_to_many"); + dbSettings.put(Environment.USER, "sa"); + dbSettings.put(Environment.PASS, ""); + dbSettings.put(Environment.DRIVER, "org.h2.Driver"); + dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + dbSettings.put(Environment.SHOW_SQL, "true"); + dbSettings.put(Environment.HBM2DDL_AUTO, "create"); + return dbSettings; + } +} diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java new file mode 100644 index 0000000000..c34b77282c --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java @@ -0,0 +1,67 @@ +package com.baeldung.hibernate; + +import com.google.common.base.Preconditions; +import java.util.Properties; +import javax.sql.DataSource; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.show_sql", "false"); + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java new file mode 100644 index 0000000000..0f995bfe03 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java @@ -0,0 +1,43 @@ +package com.baeldung.hibernate.subselect; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import java.time.Instant; +import lombok.Data; +import lombok.experimental.Accessors; +import org.hibernate.annotations.Subselect; + +@Data +@Accessors(chain = true) +@Entity +// language=sql +@Subselect(value = + "SELECT\n" + + " ss.id,\n" + + " ss.attr_key,\n" + + " ss.val,\n" + + " ss.created_at\n" + + " FROM system_settings AS ss\n" + + " INNER JOIN (\n" + + " SELECT\n" + + " ss2.attr_key as k2,\n" + + " MAX(ss2.created_at) as ca2\n" + + " FROM system_settings ss2\n" + + " GROUP BY ss2.attr_key\n" + + " ) AS t ON t.k2 = ss.attr_key AND t.ca2 = ss.created_at\n" + + " WHERE ss.type = 'SYSTEM' AND ss.active IS TRUE\n") +public class RuntimeConfiguration { + + @Id + private Long id; + + @Column(name = "attr_key") + private String key; + + @Column(name = "val") + private String value; + + @Column(name = "created_at") + private Instant createdAt; +} diff --git a/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml new file mode 100644 index 0000000000..5970821ccd --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + splitting.enabled + true + true + SYSTEM + + + + + 2 + splitting.enabled + false + false + SYSTEM + + + + + 3 + redelivery.enabled + false + true + ORDER + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml new file mode 100644 index 0000000000..ba16dc7b8b --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..4bc5e98f56 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties @@ -0,0 +1,15 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + diff --git a/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..2db3ec53d5 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.hibernate.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java new file mode 100644 index 0000000000..fee67240e4 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java @@ -0,0 +1,65 @@ +package com.baeldung.hibernate.subselect; + +import com.baeldung.hibernate.HibernateAnnotationUtil; +import jakarta.persistence.criteria.Root; +import liquibase.Contexts; +import liquibase.LabelExpression; +import liquibase.Liquibase; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.LiquibaseException; +import liquibase.resource.ClassLoaderResourceAccessor; +import org.hibernate.Session; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class SubselectIntegrationTest { + + @BeforeAll + static void setUp() { + Session currentSession = HibernateAnnotationUtil.getSessionFactory().getCurrentSession(); + currentSession.beginTransaction(); + + currentSession.doWork(it -> { + Liquibase liquibase; + try { + liquibase = new Liquibase( + "migrations/master.xml", + new ClassLoaderResourceAccessor(), + DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(it)) + ); + liquibase.update(new Contexts(), new LabelExpression(),true); + } catch (LiquibaseException e) { + throw new RuntimeException(e); + } + }); + + currentSession.getTransaction().commit(); + } + + @Test + void givenEntityMarkedWithSubselect_whenSelectingRuntimeConfigByKey_thenSelectedSuccessfully() { + String key = "splitting.enabled"; + Session entityManager = HibernateAnnotationUtil.getSessionFactory().getCurrentSession(); + + entityManager.beginTransaction(); + + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + + CriteriaQuery query = criteriaBuilder.createQuery(RuntimeConfiguration.class); + + Root root = query.from(RuntimeConfiguration.class); + + RuntimeConfiguration configurationParameter = entityManager.createQuery( + query.select(root).where(criteriaBuilder.equal(root.get("key"), key)) + ).getSingleResult(); + + entityManager.getTransaction().commit(); + + Assertions.assertThat(configurationParameter.getValue()).isEqualTo("true"); + } +} + diff --git a/persistence-modules/hibernate-annotations/README.md b/persistence-modules/hibernate-annotations/README.md index 663c39ea33..446dde9ece 100644 --- a/persistence-modules/hibernate-annotations/README.md +++ b/persistence-modules/hibernate-annotations/README.md @@ -13,3 +13,4 @@ This module contains articles about Annotations used in Hibernate. - [Hibernate @CreationTimestamp and @UpdateTimestamp](https://www.baeldung.com/hibernate-creationtimestamp-updatetimestamp) - [Difference Between @JoinColumn and @PrimaryKeyJoinColumn in JPA](https://www.baeldung.com/java-jpa-join-vs-primarykeyjoin) - [A Guide to the @SoftDelete Annotation in Hibernate](https://www.baeldung.com/java-hibernate-softdelete-annotation) +- [@Subselect Annotation in Hibernate](https://www.baeldung.com/hibernate-subselect) diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml index 6f11888643..12a5298e95 100644 --- a/persistence-modules/hibernate-annotations/pom.xml +++ b/persistence-modules/hibernate-annotations/pom.xml @@ -81,6 +81,16 @@ hypersistence-utils-hibernate-60 ${hypersistance-utils-hibernate-60.version} + + org.liquibase + liquibase-core + ${liquibase-core.version} + + + org.projectlombok + lombok + ${lombok.version} + @@ -91,6 +101,8 @@ true 9.0.0.M26 3.3.1 + 1.18.30 + 4.24.0 \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/README.md b/persistence-modules/hibernate-jpa/README.md index 5599140732..feab5f4d9a 100644 --- a/persistence-modules/hibernate-jpa/README.md +++ b/persistence-modules/hibernate-jpa/README.md @@ -13,4 +13,5 @@ This module contains articles specific to use of Hibernate as a JPA implementati - [Enabling Transaction Locks in Spring Data JPA](https://www.baeldung.com/java-jpa-transaction-locks) - [JPA/Hibernate Persistence Context](https://www.baeldung.com/jpa-hibernate-persistence-context) - [Quick Guide to EntityManager#getReference()](https://www.baeldung.com/jpa-entity-manager-get-reference) -- [JPA Entities and the Serializable Interface](https://www.baeldung.com/jpa-entities-serializable) \ No newline at end of file +- [JPA Entities and the Serializable Interface](https://www.baeldung.com/jpa-entities-serializable) +- [The @Struct Annotation Type in Hibernate – Structured User-Defined Types](https://www.baeldung.com/java-hibernate-struct-annotation) diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructDepartment.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructDepartment.java new file mode 100644 index 0000000000..419c47791a --- /dev/null +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructDepartment.java @@ -0,0 +1,51 @@ +package com.baeldung.hibernate.struct.entities; + +import jakarta.persistence.*; + +@Entity +public class StructDepartment { + @Id + @GeneratedValue + private Integer id; + + @Column + private String departmentName; + + @Embedded + @Column + private StructManager manager; + + @Override + public String toString() { + return "Department{" + + "id=" + id + + ", departmentName='" + departmentName + '\'' + + ", manager=" + manager + + '}'; + } + + public StructDepartment(String departmentName, StructManager manager) { + this.departmentName = departmentName; + this.manager = manager; + } + + public Integer getId() { + return id; + } + + public String getDepartmentName() { + return departmentName; + } + + public void setDepartmentName(String departmentName) { + this.departmentName = departmentName; + } + + public StructManager getManager() { + return manager; + } + + public void setManager(StructManager manager) { + this.manager = manager; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructManager.java b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructManager.java new file mode 100644 index 0000000000..10595ecc55 --- /dev/null +++ b/persistence-modules/hibernate-jpa/src/main/java/com/baeldung/hibernate/struct/entities/StructManager.java @@ -0,0 +1,52 @@ +package com.baeldung.hibernate.struct.entities; +import jakarta.persistence.Embeddable; +import org.hibernate.annotations.Struct; + +import java.io.Serializable; + +@Embeddable +@Struct(name = "Department_Manager_Type", attributes = {"firstName", "lastName", "qualification"}) +public class StructManager implements Serializable { + private String firstName; + private String lastName; + private String qualification; + + @Override + public String toString() { + return "Manager{" + + "firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", qualification='" + qualification + '\'' + + '}'; + } + + public StructManager(String firstName, String lastName, String qualification) { + this.firstName = firstName; + this.lastName = lastName; + this.qualification = qualification; + } + + 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; + } + + public String getQualification() { + return qualification; + } + + public void setQualification(String qualification) { + this.qualification = qualification; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/struct/HibernateStructUnitTest.java b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/struct/HibernateStructUnitTest.java new file mode 100644 index 0000000000..a836fe0de1 --- /dev/null +++ b/persistence-modules/hibernate-jpa/src/test/java/com/baeldung/hibernate/struct/HibernateStructUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.hibernate.struct; + +import com.baeldung.hibernate.struct.entities.StructDepartment; +import com.baeldung.hibernate.struct.entities.StructManager; +import org.apache.commons.lang3.StringUtils; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateStructUnitTest { + + private Session session; + private Transaction transaction; + + public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException { + ServiceRegistry serviceRegistry = configureServiceRegistry(properties); + return makeSessionFactory(serviceRegistry); + } + + private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addPackage("com.baeldung.hibernate.struct.entities"); + metadataSources.addAnnotatedClass(StructDepartment.class); + metadataSources.addAnnotatedClass(StructManager.class); + + Metadata metadata = metadataSources.getMetadataBuilder() + .build(); + + return metadata.getSessionFactoryBuilder() + .build(); + + } + private static ServiceRegistry configureServiceRegistry(Properties properties) throws IOException { + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + public static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate-derby.properties")); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + return configureServiceRegistry(getProperties()); + } + private static String PROPERTY_FILE_NAME; + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + ServiceRegistry serviceRegistry = configureServiceRegistry(); + return makeSessionFactory(serviceRegistry); + } + @Before + public void setUp() throws IOException { + session = getSessionFactory("hibernate-derby.properties") + .openSession(); + transaction = session.beginTransaction(); + + transaction.commit(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + + +/* This unit test is for reference only because the Hibernate dialect for + Apache Derby database does not support @Struct annotation. + + @Test + public void givenSaveDepartmentObject_ThenManagerUDTExists() { + StructDepartment d = new StructDepartment("Information Technology" + , new StructManager("Zeeshan", "Arif", "Qualified")); + + session.persist(d); + session.flush(); + session.clear(); + + }*/ +} diff --git a/persistence-modules/hibernate-jpa/src/test/resources/hibernate-derby.properties b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-derby.properties new file mode 100644 index 0000000000..72256d1687 --- /dev/null +++ b/persistence-modules/hibernate-jpa/src/test/resources/hibernate-derby.properties @@ -0,0 +1,17 @@ +hibernate.connection.driver_class=org.apache.derby.jdbc.EmbeddedDriver +hibernate.connection.url=jdbc:derby:db/derby.dbfile;create=true +hibernate.connection.username= +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.DerbyDialect + +# enable to see Hibernate generated SQL +hibernate.show_sql=false + +hibernate.hbm2ddl.auto=create-drop + +hibernate.c3p0.min_size=5 +hibernate.c3p0.max_size=20 +hibernate.c3p0.acquire_increment=5 +hibernate.c3p0.timeout=1800 diff --git a/persistence-modules/hibernate-queries/README.md b/persistence-modules/hibernate-queries/README.md index 9e6c52d6dc..60a84de779 100644 --- a/persistence-modules/hibernate-queries/README.md +++ b/persistence-modules/hibernate-queries/README.md @@ -13,3 +13,4 @@ This module contains articles about use of Queries in Hibernate. - [Distinct Queries in HQL](https://www.baeldung.com/java-hql-distinct) - [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query) - [Database Keywords as Columns in Hibernate Entities](https://www.baeldung.com/java-hibernate-db-keywords-as-columns) +- [Get List of Entity From Database in Hibernate](https://www.baeldung.com/java-hibernate-fetch-entity-list) diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Department.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Department.java new file mode 100644 index 0000000000..62a31dd344 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Department.java @@ -0,0 +1,40 @@ +package com.baeldung.hibernate.listentity.entity; + +import java.util.List; +import jakarta.persistence.*; + +@Entity +public class Department { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + @OneToMany(mappedBy = "department", fetch = FetchType.EAGER) + private List employees; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Employee.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Employee.java new file mode 100644 index 0000000000..6b4b0c56b1 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/entity/Employee.java @@ -0,0 +1,41 @@ +package com.baeldung.hibernate.listentity.entity; + +import jakarta.persistence.*; + +@Entity +@NamedQuery(name = "findAllEmployees", query = "SELECT e FROM Employee e") +@NamedQuery(name = "findEmployeesByDepartment", query = "SELECT e FROM Employee e WHERE e.department = :department ORDER BY e.lastName ASC") +public class Employee { + + @Id + @GeneratedValue + private Long id; + + private String lastName; + + private String department; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } +} diff --git a/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/service/EmployeeService.java b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/service/EmployeeService.java new file mode 100644 index 0000000000..b336fb1691 --- /dev/null +++ b/persistence-modules/hibernate-queries/src/main/java/com/baeldung/hibernate/listentity/service/EmployeeService.java @@ -0,0 +1,88 @@ +package com.baeldung.hibernate.listentity.service; + +import java.util.Collections; +import java.util.List; + +import jakarta.persistence.*; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Path; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; + +import org.springframework.stereotype.Service; + +import com.baeldung.hibernate.listentity.entity.Department; +import com.baeldung.hibernate.listentity.entity.Employee; + +@Service +public class EmployeeService { + + @PersistenceContext + private EntityManager entityManager; + + public List getAllEmployeesUsingJPQL() { + String jpqlQuery = "SELECT e FROM Employee e"; + Query query = entityManager.createQuery(jpqlQuery, Employee.class); + return query.getResultList(); + } + + public List getAllEmployeesByDepartmentUsingJPQL() { + String jpqlQuery = "SELECT e FROM Employee e WHERE e.department = 'Engineering' ORDER BY e.lastName ASC"; + Query query = entityManager.createQuery(jpqlQuery, Employee.class); + + return query.getResultList(); + } + + public List getAllEmployeesUsingNamedQuery() { + Query query = entityManager.createNamedQuery("findAllEmployees", Employee.class); + + return query.getResultList(); + } + + public List getAllEmployeesByDepartmentUsingNamedQuery(String department) { + Query query = entityManager.createNamedQuery("findEmployeesByDepartment", Employee.class); + query.setParameter("department", department); + + return query.getResultList(); + } + + public List getAllEmployeesUsingCriteriaAPI() { + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Employee.class); + Root employeeRoot = criteriaQuery.from(Employee.class); + + criteriaQuery.select(employeeRoot); + Query query = entityManager.createQuery(criteriaQuery); + + return query.getResultList(); + } + + public List getAllEmployeesByDepartmentUsingCriteriaAPI(String department) { + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Employee.class); + Root employeeRoot = criteriaQuery.from(Employee.class); + Predicate departmentPredicate = criteriaBuilder.equal(employeeRoot.get("department"), department); + Path sortByPath = employeeRoot.get("lastName"); + criteriaQuery.orderBy(criteriaBuilder.asc(sortByPath)); + criteriaQuery.select(employeeRoot) + .where(departmentPredicate); + Query query = entityManager.createQuery(criteriaQuery); + + return query.getResultList(); + } + + public List getAllEmployeesByDepartmentUsingOneToManyAnnotations(String departmentName) { + try { + // Retrieve the department by its name + Department department = entityManager.createQuery("SELECT d FROM Department d WHERE d.name = :name", Department.class) + .setParameter("name", departmentName) + .getSingleResult(); + + // Return the list of employees associated with the department + return department.getEmployees(); + } catch (NoResultException e) { + return Collections.emptyList(); + } + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java new file mode 100644 index 0000000000..a730e9bfc6 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java @@ -0,0 +1,56 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables; + + +import com.baeldung.jooq.jointables.public_.Public; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Constants; +import org.jooq.Schema; +import org.jooq.impl.CatalogImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class DefaultCatalog extends CatalogImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of DEFAULT_CATALOG + */ + public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog(); + + /** + * The schema public. + */ + public final Public PUBLIC = Public.PUBLIC; + + /** + * No further instances allowed + */ + private DefaultCatalog() { + super(""); + } + + @Override + public final List getSchemas() { + return Arrays.asList( + Public.PUBLIC + ); + } + + /** + * A reference to the 3.19 minor release of the code generator. If this + * doesn't compile, it's because the runtime library uses an older minor + * release, namely: 3.19. You can turn off the generation of this reference + * by specifying /configuration/generator/generate/jooqVersionReference + */ + private static final String REQUIRE_RUNTIME_JOOQ_VERSION = Constants.VERSION_3_19; +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java new file mode 100644 index 0000000000..2c67ef2ad3 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java @@ -0,0 +1,75 @@ +package com.baeldung.jooq.jointables; + +import static org.jooq.impl.DSL.field; + +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SelectJoinStep; + +import com.baeldung.jooq.jointables.public_.Tables; + +public class JoinTables { + + public static Result usingJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .join(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingMultipleJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .join(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))) + .join(Tables.STORE) + .on(field(Tables.BOOK.STORE_ID).eq(field(Tables.STORE.ID))); + return query.fetch(); + } + + public static Result usingLeftOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .leftOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingRightOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .rightOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingFullOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .fullOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingNaturalJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .naturalJoin(Tables.BOOKAUTHOR); + return query.fetch(); + } + + public static Result usingCrossJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.STORE) + .crossJoin(Tables.BOOK); + return query.fetch(); + } + + public static void printResult(Result result) { + for (Record record : result) { + System.out.println(record); + } + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java new file mode 100644 index 0000000000..86c1939891 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java @@ -0,0 +1,34 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; +import com.baeldung.jooq.jointables.public_.tables.records.BookRecord; +import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord; +import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord; + +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.Internal; + + +/** + * A class modelling foreign key relationships and constraints of tables in + * public. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Keys { + + // ------------------------------------------------------------------------- + // UNIQUE and PRIMARY KEY definitions + // ------------------------------------------------------------------------- + + public static final UniqueKey BOOK_PKEY = Internal.createUniqueKey(Book.BOOK, DSL.name("Book_pkey"), new TableField[] { Book.BOOK.ID }, true); + public static final UniqueKey AUTHOR_PKEY = Internal.createUniqueKey(Bookauthor.BOOKAUTHOR, DSL.name("Author_pkey"), new TableField[] { Bookauthor.BOOKAUTHOR.ID }, true); + public static final UniqueKey STORE_PKEY = Internal.createUniqueKey(Store.STORE, DSL.name("Store_pkey"), new TableField[] { Store.STORE.ID }, true); +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java new file mode 100644 index 0000000000..1b2e8dda87 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java @@ -0,0 +1,69 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.DefaultCatalog; +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Catalog; +import org.jooq.Table; +import org.jooq.impl.SchemaImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Public extends SchemaImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public + */ + public static final Public PUBLIC = new Public(); + + /** + * The table public.Book. + */ + public final Book BOOK = Book.BOOK; + + /** + * The table public.BookAuthor. + */ + public final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR; + + /** + * The table public.Store. + */ + public final Store STORE = Store.STORE; + + /** + * No further instances allowed + */ + private Public() { + super("public", null); + } + + + @Override + public Catalog getCatalog() { + return DefaultCatalog.DEFAULT_CATALOG; + } + + @Override + public final List> getTables() { + return Arrays.asList( + Book.BOOK, + Bookauthor.BOOKAUTHOR, + Store.STORE + ); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java new file mode 100644 index 0000000000..789c131a25 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java @@ -0,0 +1,32 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + + +/** + * Convenience access to all tables in public. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Tables { + + /** + * The table public.Book. + */ + public static final Book BOOK = Book.BOOK; + + /** + * The table public.BookAuthor. + */ + public static final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR; + + /** + * The table public.Store. + */ + public static final Store STORE = Store.STORE; +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java new file mode 100644 index 0000000000..4e21648cbd --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java @@ -0,0 +1,238 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.BookRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Book extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.Book + */ + public static final Book BOOK = new Book(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookRecord.class; + } + + /** + * The column public.Book.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.Book.author_id. + */ + public final TableField AUTHOR_ID = createField(DSL.name("author_id"), SQLDataType.INTEGER, this, ""); + + /** + * The column public.Book.title. + */ + public final TableField TITLE = createField(DSL.name("title"), SQLDataType.VARCHAR, this, ""); + + /** + * The column public.Book.description. + */ + public final TableField DESCRIPTION = createField(DSL.name("description"), SQLDataType.VARCHAR, this, ""); + + /** + * The column public.Book.store_id. + */ + public final TableField STORE_ID = createField(DSL.name("store_id"), SQLDataType.INTEGER, this, ""); + + private Book(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Book(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.Book table reference + */ + public Book(String alias) { + this(DSL.name(alias), BOOK); + } + + /** + * Create an aliased public.Book table reference + */ + public Book(Name alias) { + this(alias, BOOK); + } + + /** + * Create a public.Book table reference + */ + public Book() { + this(DSL.name("Book"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.BOOK_PKEY; + } + + @Override + public Book as(String alias) { + return new Book(DSL.name(alias), this); + } + + @Override + public Book as(Name alias) { + return new Book(alias, this); + } + + @Override + public Book as(Table alias) { + return new Book(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Book rename(String name) { + return new Book(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Book rename(Name name) { + return new Book(name, null); + } + + /** + * Rename this table + */ + @Override + public Book rename(Table name) { + return new Book(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Condition condition) { + return new Book(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java new file mode 100644 index 0000000000..9d828e9add --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java @@ -0,0 +1,228 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Bookauthor extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.BookAuthor + */ + public static final Bookauthor BOOKAUTHOR = new Bookauthor(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookauthorRecord.class; + } + + /** + * The column public.BookAuthor.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.BookAuthor.name. + */ + public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, ""); + + /** + * The column public.BookAuthor.country. + */ + public final TableField COUNTRY = createField(DSL.name("country"), SQLDataType.VARCHAR, this, ""); + + private Bookauthor(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Bookauthor(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.BookAuthor table reference + */ + public Bookauthor(String alias) { + this(DSL.name(alias), BOOKAUTHOR); + } + + /** + * Create an aliased public.BookAuthor table reference + */ + public Bookauthor(Name alias) { + this(alias, BOOKAUTHOR); + } + + /** + * Create a public.BookAuthor table reference + */ + public Bookauthor() { + this(DSL.name("BookAuthor"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.AUTHOR_PKEY; + } + + @Override + public Bookauthor as(String alias) { + return new Bookauthor(DSL.name(alias), this); + } + + @Override + public Bookauthor as(Name alias) { + return new Bookauthor(alias, this); + } + + @Override + public Bookauthor as(Table alias) { + return new Bookauthor(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(String name) { + return new Bookauthor(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(Name name) { + return new Bookauthor(name, null); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(Table name) { + return new Bookauthor(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Condition condition) { + return new Bookauthor(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java new file mode 100644 index 0000000000..d97f3da21b --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java @@ -0,0 +1,223 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Store extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.Store + */ + public static final Store STORE = new Store(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return StoreRecord.class; + } + + /** + * The column public.Store.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.Store.name. + */ + public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, ""); + + private Store(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Store(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.Store table reference + */ + public Store(String alias) { + this(DSL.name(alias), STORE); + } + + /** + * Create an aliased public.Store table reference + */ + public Store(Name alias) { + this(alias, STORE); + } + + /** + * Create a public.Store table reference + */ + public Store() { + this(DSL.name("Store"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.STORE_PKEY; + } + + @Override + public Store as(String alias) { + return new Store(DSL.name(alias), this); + } + + @Override + public Store as(Name alias) { + return new Store(alias, this); + } + + @Override + public Store as(Table alias) { + return new Store(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Store rename(String name) { + return new Store(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Store rename(Name name) { + return new Store(name, null); + } + + /** + * Rename this table + */ + @Override + public Store rename(Table name) { + return new Store(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Condition condition) { + return new Store(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java new file mode 100644 index 0000000000..0636ff2fdf --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java @@ -0,0 +1,124 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Book; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class BookRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.Book.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.Book.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.Book.author_id. + */ + public void setAuthorId(Integer value) { + set(1, value); + } + + /** + * Getter for public.Book.author_id. + */ + public Integer getAuthorId() { + return (Integer) get(1); + } + + /** + * Setter for public.Book.title. + */ + public void setTitle(String value) { + set(2, value); + } + + /** + * Getter for public.Book.title. + */ + public String getTitle() { + return (String) get(2); + } + + /** + * Setter for public.Book.description. + */ + public void setDescription(String value) { + set(3, value); + } + + /** + * Getter for public.Book.description. + */ + public String getDescription() { + return (String) get(3); + } + + /** + * Setter for public.Book.store_id. + */ + public void setStoreId(Integer value) { + set(4, value); + } + + /** + * Getter for public.Book.store_id. + */ + public Integer getStoreId() { + return (Integer) get(4); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookRecord + */ + public BookRecord() { + super(Book.BOOK); + } + + /** + * Create a detached, initialised BookRecord + */ + public BookRecord(Integer id, Integer authorId, String title, String description, Integer storeId) { + super(Book.BOOK); + + setId(id); + setAuthorId(authorId); + setTitle(title); + setDescription(description); + setStoreId(storeId); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java new file mode 100644 index 0000000000..0e99b2d93b --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java @@ -0,0 +1,94 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class BookauthorRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.BookAuthor.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.BookAuthor.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.BookAuthor.name. + */ + public void setName(String value) { + set(1, value); + } + + /** + * Getter for public.BookAuthor.name. + */ + public String getName() { + return (String) get(1); + } + + /** + * Setter for public.BookAuthor.country. + */ + public void setCountry(String value) { + set(2, value); + } + + /** + * Getter for public.BookAuthor.country. + */ + public String getCountry() { + return (String) get(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookauthorRecord + */ + public BookauthorRecord() { + super(Bookauthor.BOOKAUTHOR); + } + + /** + * Create a detached, initialised BookauthorRecord + */ + public BookauthorRecord(Integer id, String name, String country) { + super(Bookauthor.BOOKAUTHOR); + + setId(id); + setName(name); + setCountry(country); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java new file mode 100644 index 0000000000..f8628818e3 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java @@ -0,0 +1,79 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Store; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class StoreRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.Store.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.Store.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.Store.name. + */ + public void setName(String value) { + set(1, value); + } + + /** + * Getter for public.Store.name. + */ + public String getName() { + return (String) get(1); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached StoreRecord + */ + public StoreRecord() { + super(Store.STORE); + } + + /** + * Create a detached, initialised StoreRecord + */ + public StoreRecord(Integer id, String name) { + super(Store.STORE); + + setId(id); + setName(name); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java new file mode 100644 index 0000000000..a5daf53542 --- /dev/null +++ b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java @@ -0,0 +1,111 @@ +package com.baeldung.jooq.jointables; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.sql.DriverManager; + +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baeldung.jooq.jointables.public_.Tables; +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + +public class JoinTablesLiveTest { + + static DSLContext context; + + @BeforeClass + public static void setUp() throws Exception { + // URL jooqConfigURL = getClass().getClassLoader().getResource("jooq-config-2.xml"); + // File file = new File(jooqConfigURL.getFile()); + // GenerationTool.generate(Files.readString(file.toPath())); + + String url = "jdbc:postgresql://localhost:5432/postgres"; + String username = "postgres"; + String password = ""; + + Connection conn = DriverManager.getConnection(url, username, password); + context = DSL.using(conn, SQLDialect.POSTGRES); + + context.insertInto(Tables.STORE, Store.STORE.ID, Store.STORE.NAME) + .values(1, "ABC Branch I ") + .values(2, "ABC Branch II") + .execute(); + + context.insertInto(Tables.BOOK, Book.BOOK.ID, Book.BOOK.TITLE, Book.BOOK.DESCRIPTION, Book.BOOK.AUTHOR_ID, Book.BOOK.STORE_ID) + .values(1, "Book 1", "This is book 1", 1, 1) + .values(2, "Book 2", "This is book 2", 2, 2) + .values(3, "Book 3", "This is book 3", 1, 2) + .values(4, "Book 4", "This is book 4", 5, 1) + .execute(); + + context.insertInto(Tables.BOOKAUTHOR, Bookauthor.BOOKAUTHOR.ID, Bookauthor.BOOKAUTHOR.NAME, Bookauthor.BOOKAUTHOR.COUNTRY) + .values(1, "John Smith", "Japan") + .values(2, "William Walce", "Japan") + .values(3, "Marry Sity", "South Korea") + .values(4, "Morry Toh", "England") + .execute(); + } + + @AfterClass + public static void cleanup() throws Exception { + context.truncateTable(Store.STORE) + .execute(); + context.truncateTable(Book.BOOK) + .execute(); + context.truncateTable(Bookauthor.BOOKAUTHOR) + .execute(); + } + + @Test + public void _whenUsingJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingJoinMethod(context); + assertEquals(3, result.size()); + } + + @Test + public void _whenUsingMultipleJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingMultipleJoinMethod(context); + assertEquals(3, result.size()); + } + + @Test + public void givenContext_whenUsingLeftOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingLeftOuterJoinMethod(context); + assertEquals(4, result.size()); + } + + @Test + public void whenUsingRightOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingRightOuterJoinMethod(context); + assertEquals(5, result.size()); + } + + @Test + public void whenUsingFullOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingFullOuterJoinMethod(context); + assertEquals(6, result.size()); + } + + @Test + public void whenUsingNaturalJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingNaturalJoinMethod(context); + assertEquals(4, result.size()); + } + + @Test + public void whenUsingCrossJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingCrossJoinMethod(context); + assertEquals(8, result.size()); + } +} diff --git a/persistence-modules/jooq/src/test/resources/jooq-config-2.xml b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml new file mode 100644 index 0000000000..a644e3fef5 --- /dev/null +++ b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml @@ -0,0 +1,19 @@ + + + org.postgresql.Driver + jdbc:postgresql://localhost:5432/postgres + postgres + + + + + org.jooq.meta.postgres.PostgresDatabase + Store|Book|BookAuthor + + + + com.baeldung.jooq.jointables + src/main/java + + + diff --git a/persistence-modules/liquibase/README.md b/persistence-modules/liquibase/README.md index 0e5bfcb8a6..4b68b8b995 100644 --- a/persistence-modules/liquibase/README.md +++ b/persistence-modules/liquibase/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Introduction to Liquibase Rollback](http://www.baeldung.com/liquibase-rollback) +- [Creating PostgreSQL Schema Before Liquibase Execution](https://www.baeldung.com/java-postgresql-create-schema-before-liquibase) diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 89cc395796..16893b825f 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -24,6 +24,7 @@ core-java-persistence-2 core-java-persistence-3 couchbase + duckdb elasticsearch flyway flyway-repair @@ -88,6 +89,7 @@ spring-data-jpa-query spring-data-jpa-query-2 spring-data-jpa-query-3 + spring-data-jpa-query-4 spring-data-jpa-repo spring-data-jpa-repo-2 spring-data-jpa-repo-4 diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 75b444f7cc..d4bf8ba5cb 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -60,6 +60,11 @@ ${lombok.version} provided + + org.springframework + spring-tx + ${spring.tx.version} + @@ -84,6 +89,7 @@ 3.2.0 1.16.1 1.18.30 + 6.1.4 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java new file mode 100644 index 0000000000..6bb070cad2 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java @@ -0,0 +1,23 @@ +package com.baeldung.transactionalandasync; + +import jakarta.persistence.*; +import lombok.*; + +import java.math.BigDecimal; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(of = {"id"}) +@Table(name = "account") +@Data +public class Account { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + + @Column(name = "balance") + private BigDecimal balance; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java new file mode 100644 index 0000000000..a3c15e25eb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.transactionalandasync; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccountRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java new file mode 100644 index 0000000000..d54f90e2e5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java @@ -0,0 +1,41 @@ +package com.baeldung.transactionalandasync; + +import jakarta.transaction.Transactional; +import lombok.AllArgsConstructor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Service +@AllArgsConstructor +@Transactional +public class AccountService { + + private final AccountRepository accountRepository; + + @Async + public void transferAsync(Long depositorId, Long favoredId, BigDecimal amount) { + transfer(depositorId, favoredId, amount); + + printReceipt(); + } + + @Transactional + public void transfer(Long depositorId, Long favoredId, BigDecimal amount) { + Account depositorAccount = accountRepository.findById(depositorId) + .orElseThrow(IllegalArgumentException::new); + Account favoredAccount = accountRepository.findById(favoredId) + .orElseThrow(IllegalArgumentException::new); + + depositorAccount.setBalance(depositorAccount.getBalance().subtract(amount)); + favoredAccount.setBalance(favoredAccount.getBalance().add(amount)); + + accountRepository.save(depositorAccount); + accountRepository.save(favoredAccount); + } + + public void printReceipt() { + // logic to print the receipt + } +} diff --git a/spring-core-2/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java similarity index 55% rename from spring-core-2/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java rename to persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java index 21d031555b..403a098df8 100644 --- a/spring-core-2/src/main/java/com/baeldung/concurrentrequest/ConcurrentRequestApplication.java +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java @@ -1,11 +1,12 @@ -package com.baeldung.concurrentrequest; +package com.baeldung.transactionalandasync; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class ConcurrentRequestApplication { +public class BankAccountApplication { public static void main(String[] args) { - SpringApplication.run(ConcurrentRequestApplication.class, args); + SpringApplication.run(BankAccountApplication.class, args); } + } diff --git a/persistence-modules/spring-boot-persistence/pom.xml b/persistence-modules/spring-boot-persistence/pom.xml index 39edc01170..a816732e52 100644 --- a/persistence-modules/spring-boot-persistence/pom.xml +++ b/persistence-modules/spring-boot-persistence/pom.xml @@ -70,7 +70,6 @@ - 2.23.0 2.0.1.Final 8.2.0 com.baeldung.boot.Application diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 5252aa5481..5d31f13518 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -136,6 +136,12 @@ so test + + net.bytebuddy + byte-buddy + 1.14.13 + test + diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java index 3ad54e2267..13c1c162f1 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java @@ -5,8 +5,6 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.Application; - @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class SpringContextTest { diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/Book.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/Book.java new file mode 100644 index 0000000000..127b56ef0f --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/Book.java @@ -0,0 +1,57 @@ +package com.baeldung.criteriaquery; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import org.springframework.data.jpa.domain.Specification; + +@Entity +public class Book { + + @Id + @GeneratedValue + private Long id; + private String title; + private String author; + + public Book(String title, String author) { + this.title = title; + this.author = author; + } + + public Book() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + static Specification hasAuthor(String author) { + return (book, cq, cb) -> cb.equal(book.get("author"), author); + } + + static Specification titleContains(String title) { + return (book, cq, cb) -> cb.like(book.get("title"), "%" + title + "%"); + } + +} diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepository.java new file mode 100644 index 0000000000..61c47a1d85 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.criteriaquery; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +interface BookRepository extends JpaRepository, BookRepositoryCustom, JpaSpecificationExecutor { +} diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryCustom.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryCustom.java new file mode 100644 index 0000000000..9863cb72a3 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.baeldung.criteriaquery; + +import java.util.List; + +interface BookRepositoryCustom { + + List findBooksByAuthorNameAndTitle(String authorName, String title); + +} diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryImpl.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryImpl.java new file mode 100644 index 0000000000..c227bf6e96 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/criteriaquery/BookRepositoryImpl.java @@ -0,0 +1,39 @@ +package com.baeldung.criteriaquery; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Predicate; +import jakarta.persistence.criteria.Root; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +@Repository +public class BookRepositoryImpl implements BookRepositoryCustom { + + @Autowired + private EntityManager em; + + @Override + public List findBooksByAuthorNameAndTitle(String authorName, String title) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Book.class); + + Root book = cq.from(Book.class); + List predicates = new ArrayList<>(); + + if (authorName != null) { + predicates.add(cb.equal(book.get("author"), authorName)); + } + if (title != null) { + predicates.add(cb.like(book.get("title"), "%" + title + "%")); + } + cq.where(predicates.toArray(new Predicate[0])); + + return em.createQuery(cq).getResultList(); + } + +} diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/criteriaquery/CriteriaQueryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/criteriaquery/CriteriaQueryIntegrationTest.java new file mode 100644 index 0000000000..5f28b01997 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/criteriaquery/CriteriaQueryIntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.criteriaquery; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +import static com.baeldung.criteriaquery.Book.hasAuthor; +import static com.baeldung.criteriaquery.Book.titleContains; +import static org.junit.Assert.assertEquals; +import static org.springframework.data.jpa.domain.Specification.where; + +@DataJpaTest(showSql = false) +@RunWith(SpringRunner.class) +public class CriteriaQueryIntegrationTest { + + @PersistenceContext + private EntityManager entityManager; + @Autowired + private BookRepository repository; + + @Before + public void before() { + entityManager.persist(new Book("title1", "author1")); + entityManager.persist(new Book("title2", "author2")); + } + + @Test + public void givenAuthorAndTextInTitle_whenFindWithSpecification_ThenFound() { + List books = repository.findAll(where(hasAuthor("author1")).and(titleContains("1"))); + assertEquals(1, books.size()); + assertEquals("author1", books.get(0).getAuthor()); + assertEquals("title1", books.get(0).getTitle()); + } + + @Test + public void givenAuthorAndTextInTitle_whenFindWithCriteriaQuery_ThenFound() { + List books = repository.findBooksByAuthorNameAndTitle("author2", "2"); + assertEquals(1, books.size()); + assertEquals("author2", books.get(0).getAuthor()); + assertEquals("title2", books.get(0).getTitle()); + } + +} diff --git a/persistence-modules/spring-data-jpa-query-4/pom.xml b/persistence-modules/spring-data-jpa-query-4/pom.xml new file mode 100644 index 0000000000..3b843aed20 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + spring-data-jpa-query-4 + spring-data-jpa-query-4 + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-test + test + + + com.h2database + h2 + + + org.postgresql + postgresql + ${postgresql.version} + + + + + 42.7.1 + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntity.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntity.java new file mode 100644 index 0000000000..4cd267162f --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntity.java @@ -0,0 +1,24 @@ +package com.baeldung.spring.data.jpa.getnextseq; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; + +@Entity +public class MyEntity { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "mySeqGen") + @SequenceGenerator(name = "mySeqGen", sequenceName = "my_sequence_name", allocationSize = 1) + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} \ No newline at end of file diff --git a/docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/DockAppApplication.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityApplication.java similarity index 58% rename from docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/DockAppApplication.java rename to persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityApplication.java index e7ff52015c..4b31ad768c 100644 --- a/docker-modules/docker-compose/src/main/java/com/baeldung/docker/app/DockAppApplication.java +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityApplication.java @@ -1,13 +1,13 @@ -package com.baeldung.docker.app; +package com.baeldung.spring.data.jpa.getnextseq; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class DockAppApplication { +public class MyEntityApplication { public static void main(String[] args) { - SpringApplication.run(DockAppApplication.class, args); + SpringApplication.run(MyEntityApplication.class); } } diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepository.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepository.java new file mode 100644 index 0000000000..c864c43fda --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.data.jpa.getnextseq; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface MyEntityRepository extends JpaRepository { + + @Query(value = "SELECT NEXTVAL('my_sequence_name')", nativeQuery = true) + Long getNextSequenceValue(); +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityService.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityService.java new file mode 100644 index 0000000000..74825d2a82 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityService.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.data.jpa.getnextseq; + +import java.math.BigInteger; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.springframework.stereotype.Service; + +@Service +public class MyEntityService { + + @PersistenceContext + private EntityManager entityManager; + + public Long getNextSequenceValue(String sequenceName) { + BigInteger nextValue = (BigInteger) entityManager.createNativeQuery("SELECT NEXTVAL(:sequenceName)") + .setParameter("sequenceName", sequenceName) + .getSingleResult(); + return nextValue.longValue(); + } +} diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/Product.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/Product.java new file mode 100644 index 0000000000..ffe81fa13b --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/Product.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.data.jpa.queryjsonb; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Product { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + @Column(columnDefinition = "jsonb") + private String attributes; + + public Product() { + } + + public Product(String name, String attributes) { + this.name = name; + this.attributes = attributes; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAttributes() { + return attributes; + } + + public void setAttributes(String attributes) { + this.attributes = attributes; + } + +} diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductApplication.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductApplication.java new file mode 100644 index 0000000000..dc237ddf58 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.data.jpa.queryjsonb; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProductApplication { + + public static void main(String[] args) { + SpringApplication.run(ProductApplication.class); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepository.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepository.java new file mode 100644 index 0000000000..8667afb3f4 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepository.java @@ -0,0 +1,24 @@ +package com.baeldung.spring.data.jpa.queryjsonb; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface ProductRepository extends JpaRepository, JpaSpecificationExecutor { + @Query(value = "SELECT * FROM product WHERE attributes ->> ?1 = ?2", nativeQuery = true) + List findByAttribute(String key, String value); + + @Query(value = "SELECT * FROM product WHERE attributes -> ?1 ->> ?2 = ?3", nativeQuery = true) + List findByNestedAttribute(String key1, String key2, String value); + + @Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1) = ?2", nativeQuery = true) + List findByJsonPath(String path, String value); + + @Query(value = "SELECT * FROM product WHERE jsonb_extract_path_text(attributes, ?1, ?2) = ?3", nativeQuery = true) + List findByNestedJsonPath(String key1, String key2, String value); + + +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductSpecification.java b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductSpecification.java new file mode 100644 index 0000000000..65c9507cf0 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/queryjsonb/ProductSpecification.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.data.jpa.queryjsonb; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.springframework.data.jpa.domain.Specification; +public class ProductSpecification implements Specification { + + private final String key; + private final String value; + + public ProductSpecification(String key, String value) { + this.key = key; this.value = value; + } + + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { + return cb.equal(cb.function("jsonb_extract_path_text", String.class, root.get("attributes"), cb.literal(key)), value); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-query-4/src/main/resources/application.properties new file mode 100644 index 0000000000..de0685b9bd --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.hibernate.ddl-auto=create +spring.jpa.show-sql=true + +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE +spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepositoryIntegrationTest.java new file mode 100644 index 0000000000..3444bbbd49 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/getnextseq/MyEntityRepositoryIntegrationTest.java @@ -0,0 +1,47 @@ +package com.baeldung.spring.data.jpa.getnextseq; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +@SpringBootTest +@ActiveProfiles("test") +@Sql(scripts = "/testsequence.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +public class MyEntityRepositoryIntegrationTest { + @Autowired + private MyEntityRepository myEntityRepository; + + @Autowired + private MyEntityService myEntityService; + + @Test + void whenUsingSequenceGenerator_thenNextValueReturned() { + MyEntity entity = new MyEntity(); + myEntityRepository.save(entity); + + long generatedId = entity.getId(); + assertNotNull(generatedId); + assertEquals(1L, generatedId); + } + + + @Test + void whenUsingCustomQuery_thenNextValueReturned() { + long generatedId = myEntityRepository.getNextSequenceValue(); + assertNotNull(generatedId); + assertEquals(1L, generatedId); + } + + @Test + void whenUsingEntityManager_thenNextValueReturned() { + long generatedId = myEntityService.getNextSequenceValue("my_sequence_name"); + assertNotNull(generatedId); + assertEquals(1L, generatedId); + } + +} diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java new file mode 100644 index 0000000000..ac68d55139 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java @@ -0,0 +1,77 @@ +package com.baeldung.spring.data.jpa.queryjsonb; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.List; + +import javax.transaction.Transactional; + +import org.junit.Before; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.PageImpl; +import org.springframework.test.annotation.Commit; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.transaction.annotation.Propagation; +import com.fasterxml.jackson.databind.ObjectMapper; + +@SpringBootTest +@ActiveProfiles("test") +@Sql(scripts = "/testdata.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +public class ProductRepositoryLiveTest { + + @Autowired + private ProductRepository productRepository; + + @Test + void whenFindByAttribute_thenReturnTheObject() { + List redProducts = productRepository.findByAttribute("color", "red"); + + assertEquals(1, redProducts.size()); + assertEquals("Laptop", redProducts.get(0).getName()); + } + + @Test + void whenFindByNestedAttribute_thenReturnTheObject() { + List electronicProducts = productRepository.findByNestedAttribute("details", "category", "electronics"); + + assertEquals(1, electronicProducts.size()); + assertEquals("Headphones", electronicProducts.get(0) + .getName()); + } + + @Test + void whenFindByJsonPath_thenReturnTheObject() { + List redProducts = productRepository.findByJsonPath("color", "red"); + assertEquals(1, redProducts.size()); + assertEquals("Laptop", redProducts.get(0) + .getName()); + } + + @Test + void givenNestedJsonAttribute_whenFindByJsonPath_thenReturnTheObject() { + List electronicProducts = productRepository.findByNestedJsonPath("details", "category", "electronics"); + assertEquals(1, electronicProducts.size()); + assertEquals("Headphones", electronicProducts.get(0) + .getName()); + } + + @Test + void whenUsingJPASpecification_thenReturnTheObject() { + ProductSpecification spec = new ProductSpecification("color", "red"); + Page redProducts = productRepository.findAll(spec, Pageable.unpaged()); + + assertEquals(1, redProducts.getContent() + .size()); + assertEquals("Laptop", redProducts.getContent() + .get(0) + .getName()); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/resources/application-test.properties b/persistence-modules/spring-data-jpa-query-4/src/test/resources/application-test.properties new file mode 100644 index 0000000000..af1e12cb9c --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/test/resources/application-test.properties @@ -0,0 +1,10 @@ +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.hibernate.ddl-auto=create +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true + +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/resources/testdata.sql b/persistence-modules/spring-data-jpa-query-4/src/test/resources/testdata.sql new file mode 100644 index 0000000000..71e9a3123d --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/test/resources/testdata.sql @@ -0,0 +1,13 @@ +DELETE FROM product; + +INSERT INTO product (name, attributes) +VALUES ('Laptop', '{"color": "red", "size": "15 inch"}'); + +INSERT INTO product (name, attributes) +VALUES ('Phone', '{"color": "blue", "size": "6 inch"}'); + +INSERT INTO product (name, attributes) +VALUES ('Headphones', '{"brand": "Sony", "details": {"category": "electronics", "model": "WH-1000XM4"}}'); + +INSERT INTO product (name, attributes) +VALUES ('Laptop', '{"brand": "Dell", "details": {"category": "computers", "model": "XPS 13"}}'); \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/resources/testsequence.sql b/persistence-modules/spring-data-jpa-query-4/src/test/resources/testsequence.sql new file mode 100644 index 0000000000..518353ad12 --- /dev/null +++ b/persistence-modules/spring-data-jpa-query-4/src/test/resources/testsequence.sql @@ -0,0 +1,3 @@ +DROP SEQUENCE IF EXISTS my_sequence_name; + +CREATE SEQUENCE my_sequence_name START 1; \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-2/README.md b/persistence-modules/spring-data-jpa-repo-2/README.md index 8c588405f7..d377104c02 100644 --- a/persistence-modules/spring-data-jpa-repo-2/README.md +++ b/persistence-modules/spring-data-jpa-repo-2/README.md @@ -7,4 +7,6 @@ - [Difference Between JPA and Spring Data JPA](https://www.baeldung.com/spring-data-jpa-vs-jpa) - [Differences Between Spring Data JPA findFirst() and findTop()](https://www.baeldung.com/spring-data-jpa-findfirst-vs-findtop) - [Difference Between findBy and findAllBy in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-find-by-vs-find-all-by) +- [Calling Stored Procedures from Spring Data JPA Repositories](https://www.baeldung.com/spring-data-jpa-stored-procedures) + - More articles: [[<-- prev]](../spring-data-jpa-repo) diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/StoredProcedureApplication.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/StoredProcedureApplication.java similarity index 83% rename from persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/StoredProcedureApplication.java rename to persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/StoredProcedureApplication.java index 5f05764e21..0100beec55 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/StoredProcedureApplication.java +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/StoredProcedureApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.storedprocedure; +package com.baeldung.spring.data.persistence.storedprocedure; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/controller/CarController.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/controller/CarController.java similarity index 86% rename from persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/controller/CarController.java rename to persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/controller/CarController.java index 6aef600d01..6a12e4e93b 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/controller/CarController.java +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/controller/CarController.java @@ -1,14 +1,13 @@ -package com.baeldung.storedprocedure.controller; - -import java.util.List; +package com.baeldung.spring.data.persistence.storedprocedure.controller; +import com.baeldung.spring.data.persistence.storedprocedure.entity.Car; +import com.baeldung.spring.data.persistence.storedprocedure.service.CarService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.baeldung.storedprocedure.entity.Car; -import com.baeldung.storedprocedure.service.CarService; +import java.util.List; @RestController public class CarController { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/entity/Car.java similarity index 93% rename from persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java rename to persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/entity/Car.java index 0a61a16e24..53f1d8557e 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/entity/Car.java +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/entity/Car.java @@ -1,4 +1,4 @@ -package com.baeldung.storedprocedure.entity; +package com.baeldung.spring.data.persistence.storedprocedure.entity; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/repository/CarRepository.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/repository/CarRepository.java similarity index 87% rename from persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/repository/CarRepository.java rename to persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/repository/CarRepository.java index 3d9428628e..9366a86445 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/repository/CarRepository.java +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/repository/CarRepository.java @@ -1,14 +1,13 @@ -package com.baeldung.storedprocedure.repository; - -import java.util.List; +package com.baeldung.spring.data.persistence.storedprocedure.repository; +import com.baeldung.spring.data.persistence.storedprocedure.entity.Car; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import com.baeldung.storedprocedure.entity.Car; +import java.util.List; @Repository public interface CarRepository extends JpaRepository { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/service/CarService.java b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/service/CarService.java similarity index 81% rename from persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/service/CarService.java rename to persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/service/CarService.java index 104f46e324..ff2a20601e 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/storedprocedure/service/CarService.java +++ b/persistence-modules/spring-data-jpa-repo-2/src/main/java/com/baeldung/spring/data/persistence/storedprocedure/service/CarService.java @@ -1,12 +1,11 @@ -package com.baeldung.storedprocedure.service; - -import java.util.List; +package com.baeldung.spring.data.persistence.storedprocedure.service; +import com.baeldung.spring.data.persistence.storedprocedure.entity.Car; +import com.baeldung.spring.data.persistence.storedprocedure.repository.CarRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.storedprocedure.entity.Car; -import com.baeldung.storedprocedure.repository.CarRepository; +import java.util.List; @Service public class CarService { diff --git a/persistence-modules/spring-data-jpa-repo/src/main/resources/car-mysql.sql b/persistence-modules/spring-data-jpa-repo-2/src/main/resources/car-mysql.sql similarity index 100% rename from persistence-modules/spring-data-jpa-repo/src/main/resources/car-mysql.sql rename to persistence-modules/spring-data-jpa-repo-2/src/main/resources/car-mysql.sql diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java new file mode 100644 index 0000000000..840d26edf7 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.data.jpa.joinquery; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableAutoConfiguration +public class AppConfig { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) + .build(); + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource); + emf.setPackagesToScan("com.baeldung.spring.data.jpa.joinquery.entities" + , "com.baeldung.spring.data.jpa.joinquery.DTO" + , "com.baeldung.spring.data.jpa.joinquery.repositories"); + emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + emf.setJpaProperties(getHibernateProperties()); + return emf; + } + + @Bean + public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory.getObject()); + } + + private Properties getHibernateProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "create"); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + return properties; + } +} + + + + diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java new file mode 100644 index 0000000000..9464c25ce8 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java @@ -0,0 +1,119 @@ +package com.baeldung.spring.data.jpa.joinquery.DTO; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import org.springframework.context.annotation.Bean; + +import java.time.LocalDate; + +class DTO { + private Long customer_id; + private Long order_id; + private Long product_id; + + public DTO(Long customer_id, Long order_id, Long product_id) { + this.customer_id = customer_id; + this.order_id = order_id; + this.product_id = product_id; + } +} + +@Entity +@IdClass(DTO.class) +public class ResultDTO { + @Id + private Long customer_id; + + @Id + private Long order_id; + + @Id + private Long product_id; + + public void setCustomer_id(Long customer_id) { + this.customer_id = customer_id; + } + + public Long getProduct_id() { + return product_id; + } + + public void setProduct_id(Long product_id) { + this.product_id = product_id; + } + + public ResultDTO(Long customer_id, Long order_id, Long product_id, String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) { + this.customer_id = customer_id; + this.order_id = order_id; + this.product_id = product_id; + this.customerName = customerName; + this.customerEmail = customerEmail; + this.orderDate = orderDate; + this.productName = productName; + this.productPrice = productPrice; + } + + private String customerName; + private String customerEmail; + private LocalDate orderDate; + private String productName; + private Double productPrice; + + public Long getCustomer_id() { + return customer_id; + } + + public void setCustoemr_id(Long custoemr_id) { + this.customer_id = custoemr_id; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerEmail() { + return customerEmail; + } + + public void setCustomerEmail(String customerEmail) { + this.customerEmail = customerEmail; + } + + public Long getOrder_id() { + return order_id; + } + + public void setOrder_id(Long order_id) { + this.order_id = order_id; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getProductPrice() { + return productPrice; + } + + public void setProductPrice(Double productPrice) { + this.productPrice = productPrice; + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java new file mode 100644 index 0000000000..540ad9fc91 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java @@ -0,0 +1,66 @@ +package com.baeldung.spring.data.jpa.joinquery.DTO; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; + +import java.time.LocalDate; + +//@Entity +//@IdClass(DTO.class) +public class ResultDTO_wo_Ids { + public ResultDTO_wo_Ids(String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) { + this.customerName = customerName; + this.customerEmail = customerEmail; + this.orderDate = orderDate; + this.productName = productName; + this.productPrice = productPrice; + } + + private String customerName; + private String customerEmail; + private LocalDate orderDate; + private String productName; + private Double productPrice; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerEmail() { + return customerEmail; + } + + public void setCustomerEmail(String customerEmail) { + this.customerEmail = customerEmail; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getProductPrice() { + return productPrice; + } + + public void setProductPrice(Double productPrice) { + this.productPrice = productPrice; + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java new file mode 100644 index 0000000000..8da7aa21a2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java @@ -0,0 +1,104 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.Set; + +@Entity +public class Customer { + public Customer(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany(mappedBy = "customer" + , cascade = CascadeType.ALL) + private Set customerOrders; + + public Customer(Long id, Set customerOrders, String email, LocalDate dob, String name) { + this.id = id; + this.customerOrders = customerOrders; + this.email = email; + this.dob = dob; + this.name = name; + } + + public void setId(Long id) { + this.id = id; + } + + public void setCustomerOrders(Set customerOrders) { + this.customerOrders = customerOrders; + } + + @Override + public String toString() { + return "Patient{" + + "id=" + id + + ", orders=" + customerOrders + + ", email='" + email + '\'' + + ", dob=" + dob + + ", name='" + name + '\'' + + '}'; + } + + public Set getOrders() { + return customerOrders; + } + + public void setOrders(Set orders) { + this.customerOrders = orders; + } + + @Column + private String email; + + @Column(name = "dob", columnDefinition = "DATE") + private LocalDate dob; + + @Column + private String name; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer patient = (Customer) o; + return Objects.equals(id, patient.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public Long getId() { + return id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public LocalDate getDob() { + return dob; + } + + public void setDob(LocalDate dob) { + this.dob = dob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java new file mode 100644 index 0000000000..d147543e2f --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java @@ -0,0 +1,88 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.Set; + +@Entity +public class CustomerOrder { + public CustomerOrder(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + public void setId(Long id) { + this.id = id; + } + + public Set getProducts() { + return products; + } + + public void setProducts(Set products) { + this.products = products; + } + + @OneToMany(mappedBy = "customerOrder" + , cascade = CascadeType.ALL) + private Set products; + + @Column + private LocalDate orderDate; + + public CustomerOrder(Long id, Set products, LocalDate orderDate, Customer customer) { + this.id = id; + this.products = products; + this.orderDate = orderDate; + this.customer = customer; + } + + @Override + public String toString() { + return "Consult{" + + "id=" + id + + ", products=" + products + + ", orderDate=" + orderDate + + ", customer=" + customer + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CustomerOrder co = (CustomerOrder) o; + return Objects.equals(id, co.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="customer_id", nullable = false) + private Customer customer; + + public Long getId() { + return id; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java new file mode 100644 index 0000000000..ea18e6225e --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java @@ -0,0 +1,84 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.util.Objects; + +@Entity +public class Product { + public Product(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + public Product(Long id, String productName, Double price, CustomerOrder customerOrder) { + this.id = id; + this.productName = productName; + this.price = price; + this.customerOrder = customerOrder; + } + + @Column + private String productName; + + @Column + private Double price; + + @Override + public String toString() { + return "Dispense{" + + "id=" + id + + ", productName='" + productName + '\'' + + ", price=" + price + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product dispense = (Product) o; + return Objects.equals(id, dispense.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public CustomerOrder getCustomerOrder() { + return customerOrder; + } + + public void setCustomerOrder(CustomerOrder co) { + this.customerOrder = co; + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="customerorder_id", nullable = false) + private CustomerOrder customerOrder; +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java new file mode 100644 index 0000000000..ba7ece74b8 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.jpa.joinquery.repositories; + +import com.baeldung.spring.data.jpa.joinquery.entities.Customer; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends CrudRepository { +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java new file mode 100644 index 0000000000..056c91f973 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.data.jpa.joinquery.repositories; + +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Map; + +@Repository +public interface JoinRepository extends CrudRepository { + @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO(c.id, o.id, p.id, c.name, c.email, o.orderDate, p.productName, p.price) " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer.id " + + " and o.id=p.customerOrder.id " + + " and c.id=?1 ") + List findResultDTOByCustomer(Long id); + + @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids(c.name, c.email, o.orderDate, p.productName, p.price) " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer.id " + + " and o.id=p.customerOrder.id " + + " and c.id=?1 ") + List findResultDTOByCustomerWithoutIds(Long id); + + @Query(value = "SELECT c.*, o.*, p.* " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer_id " + + " and o.id=p.customerOrder_id " + + " and c.id=?1 " + , nativeQuery = true) + List> findByCustomer(Long id); +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java new file mode 100644 index 0000000000..dd91399128 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.spring.data.jpa.joinquery; + +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids; +import com.baeldung.spring.data.jpa.joinquery.entities.Customer; +import com.baeldung.spring.data.jpa.joinquery.entities.CustomerOrder; +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; +import com.baeldung.spring.data.jpa.joinquery.entities.Product; +import com.baeldung.spring.data.jpa.joinquery.repositories.CustomerRepository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.PersistenceUnit; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import com.baeldung.spring.data.jpa.joinquery.repositories.JoinRepository; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { AppConfig.class }) +class JoinRepositoryUnitTest { + + @Autowired + JoinRepository joinRepository; + + @Autowired + CustomerRepository customerRepository; + + @PersistenceUnit + EntityManagerFactory entityManagerFactory; + + EntityManager entityManager; + + @BeforeEach + void setUp() { + customerRepository.deleteAll(); + entityManager = entityManagerFactory.createEntityManager(); + Customer c = new Customer(1L, null, "email1@email.com", LocalDate.now(), "Customer"); + CustomerOrder o1 = new CustomerOrder(1L, null, LocalDate.now(), c); + CustomerOrder o2 = new CustomerOrder(2L, null, LocalDate.of(2024,1,1), c); + + Product p1 = new Product(1L,"Product1", 25.20, o1); + Product p2 = new Product(2L, "Product2", 26.20, o1); + Product p3 = new Product(3L, "Product3", 27.20, o2); + + Set cos01 = new HashSet<>(); + cos01.add(o1); + cos01.add(o2); + Set productsO1 = new HashSet<>(); + productsO1.add(p1); + productsO1.add(p2); + Set productsO2 = new HashSet<>(); + productsO1.add(p3); + + c.setCustomerOrders(cos01); + o1.setProducts(productsO1); + o2.setProducts(productsO2); + + EntityTransaction et = getTransaction(); + entityManager.persist(c); + entityManager.flush(); + et.commit(); + } + + @AfterEach + void tearDown() { + } + + @Test + void whenFindResultDTOByCustomer_thenReturnResultDTO() { + List resultDTO = joinRepository.findResultDTOByCustomer(1L); + assertInstanceOf(ResultDTO.class, resultDTO.get(0)); + } + + @Test + void whenFindByCustomerNativeQuery_thenReturnMapsForObjects() { + List> res = joinRepository.findByCustomer(1L); + //the map objects in the res List has 9 String keys aka 9 columns corresponding to the columns of customer, customerOrder, product + res.forEach(map -> { + assertEquals(9, map.keySet().size()); + }); + } + + @Test + void whenFindResultDTOByCustomerWithoutIds_thenReturnResultDTO() { + List resultDTO = joinRepository.findResultDTOByCustomerWithoutIds(1L); + assertInstanceOf(ResultDTO_wo_Ids.class, resultDTO.get(0)); + } + + private EntityTransaction getTransaction() { + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + return transaction; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo/README.md b/persistence-modules/spring-data-jpa-repo/README.md index f404263159..ffbd57d7f6 100644 --- a/persistence-modules/spring-data-jpa-repo/README.md +++ b/persistence-modules/spring-data-jpa-repo/README.md @@ -8,7 +8,6 @@ This module contains articles about repositories in Spring Data JPA - [Spring Data JPA – Adding a Method in All Repositories](https://www.baeldung.com/spring-data-jpa-method-in-all-repositories) - [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories) - [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators) -- [Calling Stored Procedures from Spring Data JPA Repositories](https://www.baeldung.com/spring-data-jpa-stored-procedures) - [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries) - More articles: [[--> next]](../spring-data-jpa-repo-2) diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/ModifyingApplication.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/ModifyingApplication.java index 8744220a0e..af7fa9a9f1 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/ModifyingApplication.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/ModifyingApplication.java @@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication -@EnableJpaRepositories("com.baeldung.jpa.modifying") -@EntityScan("com.baeldung.jpa.modifying") +@EnableJpaRepositories("com.baeldung.jpa.modifying.repository") +@EntityScan("com.baeldung.jpa.modifying.model") public class ModifyingApplication { public static void main(String[] args) { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/Possession.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/Possession.java index bc1077a3bf..b7e6051810 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/Possession.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/Possession.java @@ -78,9 +78,7 @@ public class Possession { @Override public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("Possesion [id=").append(id).append(", name=").append(name).append("]"); - return builder.toString(); + return "Possession [id=" + id + ", name=" + name + "]"; } } diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/User.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/User.java index 651e94fef0..846d2532e5 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/User.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/model/User.java @@ -96,9 +96,7 @@ public class User { @Override public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("User [name=").append(name).append(", id=").append(id).append("]"); - return builder.toString(); + return "User [name=" + name + ", id=" + id + "]"; } @Override diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/dao/UserRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/repository/UserRepository.java similarity index 96% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/dao/UserRepository.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/repository/UserRepository.java index 34a88ae2da..3c3f9dc1b3 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/dao/UserRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/modifying/repository/UserRepository.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.modifying.dao; +package com.baeldung.jpa.modifying.repository; import java.time.LocalDate; import java.util.List; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/PersistenceProductConfiguration.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/config/PersistenceProductConfiguration.java similarity index 98% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/PersistenceProductConfiguration.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/config/PersistenceProductConfiguration.java index a9702a3f54..77ca127d33 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/PersistenceProductConfiguration.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/paginationsorting/config/PersistenceProductConfiguration.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.paginationsorting; +package com.baeldung.jpa.paginationsorting.config; import java.util.HashMap; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/User.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/model/User.java similarity index 92% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/User.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/model/User.java index 68b66d0801..941d045f15 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/User.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/model/User.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.query; +package com.baeldung.jpa.query.model; import java.time.LocalDate; import java.util.Objects; @@ -106,9 +106,7 @@ public class User { @Override public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("User [name=").append(name).append(", id=").append(id).append("]"); - return builder.toString(); + return "User [name=" + name + ", id=" + id + "]"; } @Override diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepository.java similarity index 97% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepository.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepository.java index c70552e029..45739aadd4 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepository.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.query; +package com.baeldung.jpa.query.repository; import java.util.Collection; import java.util.List; @@ -12,6 +12,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import com.baeldung.jpa.query.model.User; + @Repository public interface UserRepository extends JpaRepository, UserRepositoryCustom { @Query("SELECT u FROM User u WHERE u.status = 1") diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustom.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustom.java similarity index 77% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustom.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustom.java index 22fbdab7f5..e9f906fedf 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustom.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustom.java @@ -1,10 +1,12 @@ -package com.baeldung.jpa.query; +package com.baeldung.jpa.query.repository; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; +import com.baeldung.jpa.query.model.User; + public interface UserRepositoryCustom { List findUserByEmails(Set emails); diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustomImpl.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustomImpl.java similarity index 95% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustomImpl.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustomImpl.java index 4f7d8064b9..f1c85e95e2 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/UserRepositoryCustomImpl.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/query/repository/UserRepositoryCustomImpl.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.query; +package com.baeldung.jpa.query.repository; import java.util.ArrayList; import java.util.Collection; @@ -7,6 +7,8 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.baeldung.jpa.query.model.User; + import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.persistence.criteria.CriteriaBuilder; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java index 36a1fa9389..b142933240 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java @@ -32,7 +32,7 @@ public class PersistenceConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan("com.baeldung.jpa.simple.entity"); + em.setPackagesToScan("com.baeldung.jpa.simple.model"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java similarity index 96% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java index 0e01e983b5..30e9003b2f 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java similarity index 97% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java index bf82ab61f7..5cabacf389 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import java.io.Serializable; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java similarity index 97% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java index 07759af0fb..f9a2db8437 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import java.time.ZonedDateTime; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java index e1540c64bf..e7a781defd 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java @@ -5,7 +5,7 @@ import java.util.List; import org.springframework.data.repository.ListCrudRepository; import org.springframework.stereotype.Repository; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; @Repository public interface BookListRepository extends ListCrudRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java index cb519ed5ea..b802406c1b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java @@ -7,7 +7,7 @@ import org.springframework.data.repository.ListCrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; @Repository public interface BookPagingAndSortingRepository extends PagingAndSortingRepository, ListCrudRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java index d6d1d46122..20123c73cd 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java @@ -4,7 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; public interface IFooDAO extends JpaRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java index cc13aac5db..368a0bcb5b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java @@ -6,7 +6,7 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; public interface UserRepository extends JpaRepository, UserRepositoryCustom { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java index 8584f3f3bb..e4e1a3e73b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; public interface UserRepositoryCustom { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java index b60ca65d0a..b702735b97 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java @@ -7,7 +7,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java index f02c1eebad..93d405c689 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java @@ -3,7 +3,7 @@ package com.baeldung.jpa.simple.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; import com.baeldung.jpa.simple.repository.IFooDAO; @Service diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java index 4fc56bde87..f2950b81fb 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.simple.service; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; public interface IFooService { Foo create(Foo foo); diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/modifying/UserRepositoryCommonIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/modifying/UserRepositoryCommonIntegrationTest.java index fd34d0116f..872f1be985 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/modifying/UserRepositoryCommonIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/modifying/UserRepositoryCommonIntegrationTest.java @@ -19,7 +19,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.transaction.annotation.Transactional; -import com.baeldung.jpa.modifying.dao.UserRepository; +import com.baeldung.jpa.modifying.repository.UserRepository; import com.baeldung.jpa.modifying.model.User; import jakarta.persistence.EntityManager; diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/paginationsorting/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/paginationsorting/ProductRepositoryIntegrationTest.java index 861633242d..9cf65fa949 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/paginationsorting/ProductRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/paginationsorting/ProductRepositoryIntegrationTest.java @@ -1,9 +1,9 @@ package com.baeldung.jpa.paginationsorting; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.List; diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/query/UserQueryRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/query/UserQueryRepositoryIntegrationTest.java index 2c85b3b1b3..a663408a6b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/query/UserQueryRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/query/UserQueryRepositoryIntegrationTest.java @@ -17,6 +17,9 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.JpaSort; import org.springframework.data.mapping.PropertyReferenceException; +import com.baeldung.jpa.query.model.User; +import com.baeldung.jpa.query.repository.UserRepository; + @DataJpaTest(properties = "spring.sql.init.data-locations=classpath:insert_users.sql", showSql = false) @AutoConfigurationPackage(basePackages = "com.baeldung.jpa.query") class UserQueryRepositoryIntegrationTest { diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java index ec2ada1e52..f393e305bc 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java @@ -1,14 +1,15 @@ package com.baeldung.jpa.simple; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; import com.baeldung.jpa.simple.repository.BookListRepository; @SpringBootTest(classes = JpaApplication.class) @@ -25,6 +26,6 @@ class BookListRepositoryIntegrationTest { bookListRepository.saveAll(Arrays.asList(book1, book2, book3)); List books = bookListRepository.findBooksByAuthor("John Doe"); - Assertions.assertEquals(3, books.size()); + assertEquals(3, books.size()); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java index d5c8c1bca0..390308b5ba 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java @@ -1,9 +1,11 @@ package com.baeldung.jpa.simple; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.Assertions; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -11,7 +13,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; import com.baeldung.jpa.simple.repository.BookPagingAndSortingRepository; @SpringBootTest @@ -29,8 +31,8 @@ class BookPagingAndSortingRepositoryIntegrationTest { Pageable pageable = PageRequest.of(0, 2, Sort.by("title").descending()); List books = bookPagingAndSortingRepository.findBooksByAuthor("John Miller", pageable); - Assertions.assertEquals(2, books.size()); - Assertions.assertEquals(book3.getId(), books.get(0).getId()); - Assertions.assertEquals(book2.getId(), books.get(1).getId()); + assertEquals(2, books.size()); + assertEquals(book3.getId(), books.get(0).getId()); + assertEquals(book2.getId(), books.get(1).getId()); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java index 7e2dd98ada..d4a4c2a2f7 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; import com.baeldung.jpa.simple.service.IFooService; @RunWith(SpringRunner.class) diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java index 37afc90b59..c690d601e2 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; import com.baeldung.jpa.simple.repository.UserRepository; @ExtendWith(SpringExtension.class) diff --git a/persistence-modules/spring-data-neo4j/pom.xml b/persistence-modules/spring-data-neo4j/pom.xml index 8a0a9ff464..a1d1e4660e 100644 --- a/persistence-modules/spring-data-neo4j/pom.xml +++ b/persistence-modules/spring-data-neo4j/pom.xml @@ -48,6 +48,8 @@ 2.7.14 5.10.0 + 1.7.32 + 1.2.7 \ No newline at end of file diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index 9e3903a587..ff4732926c 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -90,7 +90,9 @@ 3.2.4 0.10.0 0.6 - 4.3.2 + 5.1.2 + 3.2.0 + 5.10.2 com.baeldung.spring.data.redis.SpringRedisApplication diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml index c486a95e96..04c0dfe297 100644 --- a/persistence-modules/spring-persistence-simple/pom.xml +++ b/persistence-modules/spring-persistence-simple/pom.xml @@ -101,6 +101,8 @@ 2.2.7.RELEASE 0.23.0 2.5.2 + 1.7.32 + 1.2.7 \ No newline at end of file diff --git a/pom.xml b/pom.xml index a9b80de9c4..60d42c5517 100644 --- a/pom.xml +++ b/pom.xml @@ -118,6 +118,9 @@ **/JdbcTest.java **/*LiveTest.java + + ${tutorialsproject.basedir}/${logback.configurationFileName} + @@ -231,7 +234,7 @@ - com.vackosar.gitflowincrementalbuilder + io.github.gitflow-incremental-builder gitflow-incremental-builder ${gitflow-incremental-builder.version} @@ -318,9 +321,6 @@ **/JdbcTest.java **/*LiveTest.java - - ${tutorialsproject.basedir}/logback-config.xml - @@ -388,9 +388,6 @@ **/*JdbcTest.java **/*LiveTest.java - - ${tutorialsproject.basedir}/logback-config.xml - @@ -471,9 +468,6 @@ **/*IntegrationTest.java **/*IntTest.java - - ${tutorialsproject.basedir}/logback-config.xml - @@ -530,9 +524,6 @@ **/*IntegrationTest.java **/*IntTest.java - - ${tutorialsproject.basedir}/logback-config.xml - @@ -683,7 +674,6 @@ di-modules disruptor docker-modules - dozer drools dubbo feign @@ -836,6 +826,7 @@ spring-reactive-modules spring-remoting-modules spring-scheduling + spring-scheduling-2 spring-security-modules spring-shell spring-soap @@ -931,7 +922,6 @@ di-modules disruptor docker-modules - dozer drools dubbo feign @@ -1085,6 +1075,7 @@ spring-reactive-modules spring-remoting-modules spring-scheduling + spring-scheduling-2 spring-security-modules spring-shell spring-soap @@ -1153,29 +1144,30 @@ false false true + .*gradle-modules.* 4.13.2 3.21.0 2.2 1.3 - 4.4.0 + 5.11.0 1.14.11 - 1.7.32 - 1.2.7 + 2.0.12 + 1.5.3 2.22.2 - 3.12.1 - 3.1.0 + 3.13.0 + 3.2.0 1.8 1.2.17 1.37 1.37 - 3.1.2 + 3.2.5 4.4 2.15.1 3.14.0 @@ -1193,13 +1185,15 @@ 1.0 3.1.1 0.0.1 - 3.12.2 + 4.5.3 3.3.0 3.21.0 1.18.30 - 2.1.214 + 2.2.224 33.0.0-jre 3.3.0 + + logback-config-global.xml diff --git a/protobuffer/README.md b/protobuffer/README.md index 329ad0e071..6d742837fd 100644 --- a/protobuffer/README.md +++ b/protobuffer/README.md @@ -5,3 +5,4 @@ This module contains articles about Google Protocol Buffer. ### Relevant articles - [Introduction to Google Protocol Buffer](https://www.baeldung.com/google-protocol-buffer) +- [Convert Google Protocol Buffer Timestamp to LocalDate](https://www.baeldung.com/convert-google-protocol-buffer-timestamp-to-localdate) diff --git a/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampInstance.java b/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampInstance.java new file mode 100644 index 0000000000..0544c698f3 --- /dev/null +++ b/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampInstance.java @@ -0,0 +1,21 @@ +package com.baeldung.protobuftimestamptolocaldate; + +import com.google.protobuf.Timestamp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; + +public class TimestampInstance { + + private static final Logger logger = LoggerFactory.getLogger(TimestampInstance.class); + + public static void main(String[] args) { + Instant currentTimestamp = Instant.now(); + Timestamp timestamp = Timestamp.newBuilder() + .setSeconds(currentTimestamp.getEpochSecond()) + .setNanos(currentTimestamp.getNano()) + .build(); + logger.info(timestamp.toString()); + } +} diff --git a/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDate.java b/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDate.java new file mode 100644 index 0000000000..97caf8ad64 --- /dev/null +++ b/protobuffer/src/main/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDate.java @@ -0,0 +1,19 @@ +package com.baeldung.protobuftimestamptolocaldate; + +import com.google.protobuf.Timestamp; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; + +public class TimestampToLocalDate { + + public static LocalDate convertToLocalDate(Timestamp timestamp) { + Instant instant = Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()); + LocalDate time = instant.atZone(ZoneId.of("America/Montreal")) + .toLocalDate(); + return time; + + } + +} diff --git a/protobuffer/src/test/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDateUnitTest.java b/protobuffer/src/test/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDateUnitTest.java new file mode 100644 index 0000000000..bde8a98ac9 --- /dev/null +++ b/protobuffer/src/test/java/com/baeldung/protobuftimestamptolocaldate/TimestampToLocalDateUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.protobuftimestamptolocaldate; + +import com.google.protobuf.Timestamp; +import org.junit.Test; + +import java.time.LocalDate; + +import static org.junit.Assert.assertEquals; + +public class TimestampToLocalDateUnitTest { + + @Test + public void givenTimestamp_whenConvertedToLocalDate_thenSuccess() { + Timestamp timestamp = Timestamp.newBuilder() + .setSeconds(1000000000) + .setNanos(778866000) + .build(); + LocalDate time = TimestampToLocalDate.convertToLocalDate(timestamp); + assertEquals(LocalDate.of(2001, 9, 8), time); + } + +} \ No newline at end of file diff --git a/quarkus-modules/quarkus-virtual-threads/pom.xml b/quarkus-modules/quarkus-virtual-threads/pom.xml index f2da9390b5..0b8cf46c3e 100644 --- a/quarkus-modules/quarkus-virtual-threads/pom.xml +++ b/quarkus-modules/quarkus-virtual-threads/pom.xml @@ -37,7 +37,6 @@ 3.0.0 0.3.0 3.6.0 - 3.11.2 @@ -92,7 +91,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test diff --git a/quarkus-modules/quarkus/pom.xml b/quarkus-modules/quarkus/pom.xml index fc3d294beb..5ddd9826e9 100644 --- a/quarkus-modules/quarkus/pom.xml +++ b/quarkus-modules/quarkus/pom.xml @@ -180,7 +180,7 @@ 2.16.3.Final - 3.3.0 + 4.4.0 \ No newline at end of file diff --git a/spring-5-rest-docs/.gitignore b/spring-5-rest-docs/.gitignore new file mode 100644 index 0000000000..dec013dfa4 --- /dev/null +++ b/spring-5-rest-docs/.gitignore @@ -0,0 +1,12 @@ +#folders# +.idea +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-5-rest-docs/README.md b/spring-5-rest-docs/README.md new file mode 100644 index 0000000000..02c018a07c --- /dev/null +++ b/spring-5-rest-docs/README.md @@ -0,0 +1,8 @@ +## Spring 5 REST Docs + +This module contains articles about Spring 5 + +### Relevant Articles + +- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs) +- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters) diff --git a/spring-5-rest-docs/pom.xml b/spring-5-rest-docs/pom.xml new file mode 100644 index 0000000000..c1f5dc0681 --- /dev/null +++ b/spring-5-rest-docs/pom.xml @@ -0,0 +1,118 @@ + + + 4.0.0 + spring-5 + 0.0.1-SNAPSHOT + spring-5 + jar + spring 5 sample project about new features + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-hateoas + + + com.h2database + h2 + runtime + + + org.springframework + spring-test + + + org.springframework.security + spring-security-test + test + + + org.junit.jupiter + junit-jupiter-api + + + + org.springframework.restdocs + spring-restdocs-mockmvc + test + + + org.springframework.restdocs + spring-restdocs-restassured + test + + + org.springframework.restdocs + spring-restdocs-webtestclient + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.Spring5Application + JAR + + + + org.asciidoctor + asciidoctor-maven-plugin + ${asciidoctor-plugin.version} + + + generate-docs + package + + process-asciidoc + + + html + book + + ${snippetsDirectory} + + src/docs/asciidocs + target/generated-docs + + + + + + + + + 2.2.6 + ${project.build.directory}/generated-snippets + true + + + \ No newline at end of file diff --git a/spring-5/src/docs/asciidocs/api-guide.adoc b/spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc similarity index 100% rename from spring-5/src/docs/asciidocs/api-guide.adoc rename to spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/IndexController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/IndexController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 38cbbc8bf0..2bc981f9db 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -10,30 +10,11 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 - - - - org.junit - junit-bom - ${junit-jupiter.version} - pom - import - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - org.springframework.boot @@ -110,14 +91,6 @@ org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-compiler-plugin - - 16 - 16 - - @@ -126,6 +99,9 @@ 3.1.8 1.16.2 5.0.0-alpha.12 + true + 3.2.2 + 5.10.2 \ No newline at end of file diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java new file mode 100644 index 0000000000..5401a4d133 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java @@ -0,0 +1,12 @@ +package com.baeldung.webflux.exceptionhandeling.ex; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java new file mode 100644 index 0000000000..6bc39da062 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java @@ -0,0 +1,29 @@ +package com.baeldung.webflux.exceptionhandeling.model; + +public class User { + private String id; + private String username; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User(String userId, String userName) { + this.id = userId; + this.username = userName; + + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java new file mode 100644 index 0000000000..8c153aa2e6 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java @@ -0,0 +1,22 @@ +package com.baeldung.webflux.exceptionhandeling.repository; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.stereotype.Repository; + +import com.baeldung.webflux.exceptionhandeling.model.User; + +@Repository +public class UserRepository { + private final Map userDatabase = new ConcurrentHashMap<>(); + + public UserRepository() { + userDatabase.put("1", new User("1", "John Doe")); + userDatabase.put("2", new User("2", "Jane Smith")); + } + + public User findById(String id) { + return userDatabase.get(id); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java new file mode 100644 index 0000000000..da5a672183 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java @@ -0,0 +1,34 @@ +package com.baeldung.webflux.exceptionhandeling.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.model.User; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; + +import reactor.core.publisher.Mono; + +public class UserService { + + private final UserRepository userRepository; + + @Autowired + public UserService(UserRepository userRepository) { + this.userRepository = userRepository; + } + + public Mono getUserByIdThrowingException(String id) { + User user = userRepository.findById(id); + if (user == null) + throw new NotFoundException("User Not Found"); + return Mono.justOrEmpty(user); + } + + public Mono getUserByIdUsingMonoError(String id) { + User user = userRepository.findById(id); + return (user != null) ? Mono.justOrEmpty(user) : Mono.error(new NotFoundException("User Not Found")); + + } +} diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml index 48b68c6bf1..a81845477f 100644 --- a/spring-5-webflux-2/src/main/resources/logback.xml +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -1,12 +1,9 @@ - - - - %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable - - + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %kvp%n + diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java new file mode 100644 index 0000000000..e968cfeea3 --- /dev/null +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.webflux.exceptionhandeling; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.model.User; +import com.baeldung.webflux.exceptionhandeling.service.UserService; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; + +public class UserControllerUnitTest { + UserRepository repositoryMock = mock(UserRepository.class); + private final UserService userService = new UserService(repositoryMock); + + @Test + public void givenNonExistUser_whenFailureCall_then_Throws_exception() { + assertThrows(NotFoundException.class, () -> userService.getUserByIdThrowingException("3")); + + } + + @Test + public void givenNonExistUser_whenFailureCall_then_returnMonoError() { + Mono result = userService.getUserByIdUsingMonoError("3"); + StepVerifier.create(result) + .expectError(NotFoundException.class) + .verify(); + + } + +} diff --git a/spring-5-webflux-2/src/test/resources/logback-test.xml b/spring-5-webflux-2/src/test/resources/logback-test.xml index 12cedf5952..254798dc62 100644 --- a/spring-5-webflux-2/src/test/resources/logback-test.xml +++ b/spring-5-webflux-2/src/test/resources/logback-test.xml @@ -1,12 +1,5 @@ - - - - %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable - - - diff --git a/spring-5-webflux/pom.xml b/spring-5-webflux/pom.xml index 62a463a5cd..f0de0e5dcb 100644 --- a/spring-5-webflux/pom.xml +++ b/spring-5-webflux/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -90,12 +90,22 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + + true + + 5.0.0-alpha.12 2.0.0-Beta4 + true + 3.2.2 + 5.10.2 \ No newline at end of file diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/responsestatus/ResponseStatusController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/responsestatus/ResponseStatusController.java index bc4f628ab1..121608e7c2 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/responsestatus/ResponseStatusController.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/responsestatus/ResponseStatusController.java @@ -18,18 +18,18 @@ import static org.springframework.web.reactive.function.server.RequestPredicates @RestController public class ResponseStatusController { - @GetMapping(value = "/ok", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(value = "/ok", produces = MediaType.APPLICATION_JSON_VALUE) public Flux ok() { return Flux.just("ok"); } - @GetMapping(value = "/no-content", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(value = "/no-content", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public Flux noContent() { return Flux.empty(); } - @GetMapping(value = "/accepted", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(value = "/accepted", produces = MediaType.APPLICATION_JSON_VALUE) public Flux accepted(ServerHttpResponse response) { response.setStatusCode(HttpStatus.ACCEPTED); return Flux.just("accepted"); diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/retry/ExternalConnector.java b/spring-5-webflux/src/main/java/com/baeldung/spring/retry/ExternalConnector.java index baace095a7..597831b7e6 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/retry/ExternalConnector.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/retry/ExternalConnector.java @@ -3,6 +3,7 @@ package com.baeldung.spring.retry; import java.time.Duration; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; @@ -24,7 +25,7 @@ public class ExternalConnector { .uri(PATH_BY_ID, stockId) .accept(MediaType.APPLICATION_JSON) .retrieve() - .onStatus(HttpStatus::is5xxServerError, response -> Mono.error(new ServiceException("Server error", response.rawStatusCode()))) + .onStatus(HttpStatusCode::is5xxServerError, response -> Mono.error(new ServiceException("Server error", response.statusCode().value()))) .bodyToMono(String.class) .retryWhen(Retry.backoff(3, Duration.ofSeconds(2)) .filter(throwable -> throwable instanceof ServiceException) diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/NettyWebServerFactorySslCustomizer.java b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/NettyWebServerFactorySslCustomizer.java index cf4e5ac8ea..9ee722cb55 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/NettyWebServerFactorySslCustomizer.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/NettyWebServerFactorySslCustomizer.java @@ -20,7 +20,7 @@ public class NettyWebServerFactorySslCustomizer implements WebServerFactoryCusto ssl.setKeyStorePassword("secret"); Http2 http2 = new Http2(); http2.setEnabled(false); - serverFactory.addServerCustomizers(new SslServerCustomizer(ssl, http2, null)); + serverFactory.addServerCustomizers(new SslServerCustomizer(http2, ssl.getClientAuth(), null)); serverFactory.setPort(8443); } } diff --git a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/TimeoutController.java b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/TimeoutController.java index a4cd6bd6ba..3f0c004d6c 100644 --- a/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/TimeoutController.java +++ b/spring-5-webflux/src/main/java/com/baeldung/spring/serverconfig/TimeoutController.java @@ -14,7 +14,7 @@ public class TimeoutController { @GetMapping("/{timeout}") private Mono timeout(@PathVariable int timeout) { try { - Thread.sleep(timeout * 1000); + Thread.sleep(timeout * 1000L); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } diff --git a/spring-5-webflux/src/main/resources/logback.xml b/spring-5-webflux/src/main/resources/logback.xml index 48b68c6bf1..a81845477f 100644 --- a/spring-5-webflux/src/main/resources/logback.xml +++ b/spring-5-webflux/src/main/resources/logback.xml @@ -1,12 +1,9 @@ - - - - %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable - - + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %kvp%n + diff --git a/spring-5-webflux/src/test/resources/logback-test.xml b/spring-5-webflux/src/test/resources/logback-test.xml index 12cedf5952..c1df08bdb5 100644 --- a/spring-5-webflux/src/test/resources/logback-test.xml +++ b/spring-5-webflux/src/test/resources/logback-test.xml @@ -1,12 +1,11 @@ - - - %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable - - + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %kvp%n + + diff --git a/spring-5/README.md b/spring-5/README.md index d1487913ac..9af8bdfaf2 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -6,9 +6,7 @@ This module contains articles about Spring 5 - [Spring 5 Functional Bean Registration](https://www.baeldung.com/spring-5-functional-beans) - [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](https://www.baeldung.com/spring-5-junit-config) -- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs) - [Spring ResponseStatusException](https://www.baeldung.com/spring-response-status-exception) - [Spring Assert Statements](https://www.baeldung.com/spring-assert) - [Difference between context:annotation-config vs context:component-scan](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) - [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) -- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index d66f0fa01f..46c13cd28c 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -131,36 +131,11 @@ JAR - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-plugin.version} - - - generate-docs - package - - process-asciidoc - - - html - book - - ${snippetsDirectory} - - src/docs/asciidocs - target/generated-docs - - - - 1.0 - 2.2.6 - ${project.build.directory}/generated-snippets 5.1.0 true 2.0.1 diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index 3a60739315..7aea3b64de 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -45,6 +45,7 @@ org.mockito mockito-core + ${mockito.version} test diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 873232123b..bb1af47126 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -27,11 +27,13 @@ spring-boot-basic-customization spring-boot-basic-customization-2 spring-boot-bootstrap + spring-boot-caching + spring-boot-caching-2 spring-boot-client spring-boot-config-jpa-error spring-boot-ctx-fluent spring-boot-deployment - + spring-boot-di spring-boot-disable-logging spring-boot-ci-cd @@ -54,7 +56,7 @@ spring-boot-process-automation spring-boot-logging-logback spring-boot-logging-log4j2 - + spring-boot-mvc spring-boot-mvc-2 spring-boot-mvc-3 spring-boot-mvc-4 @@ -73,7 +75,7 @@ spring-boot-ssl-bundles spring-boot-telegram spring-boot-springdoc - + spring-boot-swagger spring-boot-swagger-jwt spring-boot-swagger-keycloak @@ -86,14 +88,13 @@ spring-boot-data-2 spring-boot-validation - - - + spring-boot-redis spring-boot-cassandre spring-boot-react + spring-caching-3 spring-boot-3-grpc - + spring-boot-3-native spring-boot-3-observation spring-boot-3-test-pitfalls spring-boot-3-testcontainers @@ -101,10 +102,10 @@ spring-boot-resilience4j spring-boot-properties spring-boot-properties-2 - + spring-boot-properties-3 spring-boot-properties-4 spring-boot-properties-migrator-demo - spring-boot-aws + spring-boot-aws spring-boot-keycloak-adapters spring-boot-mvc-legacy spring-boot-springdoc-2 @@ -113,6 +114,7 @@ spring-boot-graalvm-docker spring-boot-validations spring-boot-openapi + spring-boot-brave diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml index 29d9332ca5..d427aff835 100644 --- a/spring-boot-modules/spring-boot-3-2/pom.xml +++ b/spring-boot-modules/spring-boot-3-2/pom.xml @@ -9,10 +9,9 @@ Demo project for Spring Boot - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index ae9e9d7308..0c00a8af34 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -9,10 +9,9 @@ Demo project for Spring Boot - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml index 44cd38be3f..966dfec6fa 100644 --- a/spring-boot-modules/spring-boot-aws/pom.xml +++ b/spring-boot-modules/spring-boot-aws/pom.xml @@ -11,10 +11,9 @@ - org.springframework.boot - spring-boot-starter-parent - 2.7.11 - + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT @@ -24,8 +23,21 @@ com.amazonaws.serverless - aws-serverless-java-container-springboot2 - ${aws-serverless-java-container-springboot2.version} + aws-serverless-java-container-springboot3 + ${aws-serverless-java-container.version} + + + com.amazonaws.serverless + aws-serverless-java-container-core + ${aws-serverless-java-container.version} + tests + test-jar + test + + + org.apache.httpcomponents.client5 + httpclient5 + ${httpclient5.version} org.springframework.boot @@ -74,10 +86,11 @@ - 1.9.1 - 3.2.4 + 2.0.0 + 3.3.0 11 11 + 5.3.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml index 1b09162cf4..9018b21e03 100644 --- a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml @@ -9,10 +9,9 @@ Module For Spring Boot Basic Customization 3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/filter/AppConfig.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/filter/AppConfig.java index f90c7b2889..8108902913 100644 --- a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/filter/AppConfig.java +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/filter/AppConfig.java @@ -1,6 +1,5 @@ package com.baeldung.filter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -18,7 +17,6 @@ public class AppConfig { } @Bean - @Autowired public FilterRegistrationBean loggingFilterRegistration(LoggingService loggingService) { FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new LoggingFilterRegistrationBean(loggingService)); diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java new file mode 100644 index 0000000000..212dbd8626 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java @@ -0,0 +1,16 @@ +package com.baeldung.responsebody; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean loggingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new MD5Filter()); + return registrationBean; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java new file mode 100644 index 0000000000..657b7972bb --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java @@ -0,0 +1,15 @@ +package com.baeldung.responsebody; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/example") +public class HelloWorldController { + + @GetMapping + public String getExample() { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java new file mode 100644 index 0000000000..8f6e86f17e --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java @@ -0,0 +1,39 @@ +package com.baeldung.responsebody; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.logging.Logger; + +import org.springframework.stereotype.Component; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.xml.bind.DatatypeConverter; + +@Component +public class MD5Filter implements Filter { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + ContentCachingResponseWrapper responseCacheWrapperObject = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse); + filterChain.doFilter(servletRequest, responseCacheWrapperObject); + + byte[] responseBody = responseCacheWrapperObject.getContentAsByteArray(); + + try { + MessageDigest md5Digest = MessageDigest.getInstance("MD5"); + byte[] md5Hash = md5Digest.digest(responseBody); + String md5HashString = DatatypeConverter.printHexBinary(md5Hash); + responseCacheWrapperObject.setHeader("Response-Body-MD5", md5HashString); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + responseCacheWrapperObject.copyBodyToResponse(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java new file mode 100644 index 0000000000..4084dffccf --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.responsebody; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.responsebody") +public class ResponseBodyApplication { + + public static void main(String[] args) { + SpringApplication.run(ResponseBodyApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java new file mode 100644 index 0000000000..bebbd5a4b9 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.responsebody; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import jakarta.xml.bind.DatatypeConverter; + +@SpringBootTest(classes = ResponseBodyApplication.class) +@AutoConfigureMockMvc +class ResponseBodyUnitTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void whenExampleApiCallThenResponseHasMd5Header() throws Exception { + String endpoint = "/api/example"; + String expectedResponse = "Hello, World!"; + String expectedMD5 = getMD5Hash(expectedResponse); + + MvcResult mvcResult = mockMvc.perform(get(endpoint).accept(MediaType.TEXT_PLAIN_VALUE)) + .andExpect(status().isOk()) + .andReturn(); + + String md5Header = mvcResult.getResponse() + .getHeader("Response-Body-MD5"); + assertThat(md5Header).isEqualTo(expectedMD5); + } + + private String getMD5Hash(String input) throws NoSuchAlgorithmException { + MessageDigest md5Digest = MessageDigest.getInstance("MD5"); + byte[] md5Hash = md5Digest.digest(input.getBytes(StandardCharsets.UTF_8)); + return DatatypeConverter.printHexBinary(md5Hash); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-brave/pom.xml b/spring-boot-modules/spring-boot-brave/pom.xml new file mode 100644 index 0000000000..1cc8f44cf7 --- /dev/null +++ b/spring-boot-modules/spring-boot-brave/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + com.baeldung + spring-boot-brave + 1.0.0-SNAPSHOT + spring-boot-brave + jar + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + io.zipkin.brave + brave + 6.0.2 + + + io.zipkin.reporter2 + zipkin-reporter + 3.3.0 + + + io.zipkin.reporter2 + zipkin-sender-okhttp3 + 3.3.0 + + + io.zipkin.reporter2 + zipkin-reporter-brave + 3.3.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + \ No newline at end of file diff --git a/docker-modules/docker-images/src/main/java/com/baeldung/docker/MainApplication.java b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/Application.java similarity index 61% rename from docker-modules/docker-images/src/main/java/com/baeldung/docker/MainApplication.java rename to spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/Application.java index b5e46f3eac..7c7bc05a07 100644 --- a/docker-modules/docker-images/src/main/java/com/baeldung/docker/MainApplication.java +++ b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/Application.java @@ -1,13 +1,12 @@ -package com.baeldung.docker; +package com.baeldung.brave; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class MainApplication { +public class Application { public static void main(String[] args) { - SpringApplication.run(MainApplication .class, args); + SpringApplication.run(Application.class, args); } - } diff --git a/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/configuration/TracingConfiguration.java b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/configuration/TracingConfiguration.java new file mode 100644 index 0000000000..5b36fecce2 --- /dev/null +++ b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/configuration/TracingConfiguration.java @@ -0,0 +1,36 @@ +package com.baeldung.brave.configuration; + +import brave.Tracer; +import brave.Tracing; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import zipkin2.reporter.BytesMessageSender; +import zipkin2.reporter.brave.AsyncZipkinSpanHandler; +import zipkin2.reporter.okhttp3.OkHttpSender; + +@Configuration +public class TracingConfiguration { + + @Bean + BytesMessageSender sender() { + return OkHttpSender.create("http://127.0.0.1:9411/api/v2/spans"); + } + + @Bean + AsyncZipkinSpanHandler zipkinSpanHandler(BytesMessageSender sender) { + return AsyncZipkinSpanHandler.create(sender); + } + + @Bean + public Tracing tracing(AsyncZipkinSpanHandler zipkinSpanHandler) { + return Tracing.newBuilder() + .localServiceName("Dummy Service") + .addSpanHandler(zipkinSpanHandler) + .build(); + } + + @Bean + public Tracer tracer(Tracing tracing) { + return tracing.tracer(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/service/TracingService.java b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/service/TracingService.java new file mode 100644 index 0000000000..139718c54d --- /dev/null +++ b/spring-boot-modules/spring-boot-brave/src/main/java/com/baeldung/brave/service/TracingService.java @@ -0,0 +1,28 @@ +package com.baeldung.brave.service; + +import brave.Span; +import brave.Tracer; +import jakarta.annotation.PostConstruct; +import org.springframework.stereotype.Service; + +@Service +public class TracingService { + + private final Tracer tracer; + + public TracingService(Tracer tracer) { + this.tracer = tracer; + } + + @PostConstruct + private void postConstruct() { + Span span = tracer.nextSpan().name("Hello from Service").start(); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + span.finish(); + } + } +} diff --git a/spring-boot-modules/spring-caching-2/README.md b/spring-boot-modules/spring-boot-caching-2/README.md similarity index 85% rename from spring-boot-modules/spring-caching-2/README.md rename to spring-boot-modules/spring-boot-caching-2/README.md index fffdacdfb2..a2b0c41c63 100644 --- a/spring-boot-modules/spring-caching-2/README.md +++ b/spring-boot-modules/spring-boot-caching-2/README.md @@ -3,4 +3,5 @@ - [Setting Time-To-Live Value for Caching](https://www.baeldung.com/spring-setting-ttl-value-cache) - [Get All Cached Keys with Caffeine Cache in Spring Boot](https://www.baeldung.com/spring-boot-caffeine-spring-get-all-keys) - [Implement Two-Level Cache With Spring](https://www.baeldung.com/spring-two-level-cache) +- More articles: [[<-- prev]](/spring-boot-modules/spring-boot-caching) diff --git a/spring-boot-modules/spring-caching-2/pom.xml b/spring-boot-modules/spring-boot-caching-2/pom.xml similarity index 100% rename from spring-boot-modules/spring-caching-2/pom.xml rename to spring-boot-modules/spring-boot-caching-2/pom.xml diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/allkeys/config/AllKeysConfig.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/allkeys/service/SlowServiceWithCache.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/CacheConfig.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/CacheConfig.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/CacheConfig.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/CacheConfig.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/Item.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/Item.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/Item.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/Item.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemController.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemController.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemController.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemController.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemRepository.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemRepository.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemRepository.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemRepository.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemService.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemService.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/ItemService.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/ItemService.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/RedisCacheApplication.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/RedisCacheApplication.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/redis/RedisCacheApplication.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/redis/RedisCacheApplication.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/CachingTTLApplication.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/CachingTTLApplication.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/CachingTTLApplication.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/CachingTTLApplication.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/config/SpringCachingConfig.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/config/SpringCachingConfig.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/config/SpringCachingConfig.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/config/SpringCachingConfig.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/controller/HotelController.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/controller/HotelController.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/controller/HotelController.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/controller/HotelController.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ControllerAdvisor.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ControllerAdvisor.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ControllerAdvisor.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ControllerAdvisor.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ElementNotFoundException.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ElementNotFoundException.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ElementNotFoundException.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/exception/ElementNotFoundException.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/model/City.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/model/City.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/model/City.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/model/City.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/model/Hotel.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/model/Hotel.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/model/Hotel.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/model/Hotel.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/repository/CityRepository.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/repository/CityRepository.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/repository/CityRepository.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/repository/CityRepository.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/repository/HotelRepository.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/repository/HotelRepository.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/repository/HotelRepository.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/repository/HotelRepository.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/service/HotelService.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/service/HotelService.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/service/HotelService.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/service/HotelService.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/service/SpringCacheCustomizer.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/service/SpringCacheCustomizer.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/ttl/service/SpringCacheCustomizer.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/ttl/service/SpringCacheCustomizer.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CacheConfig.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CacheConfig.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CacheConfig.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CacheConfig.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/Customer.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/Customer.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/Customer.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/Customer.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerCacheInterceptor.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerCacheInterceptor.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerCacheInterceptor.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerCacheInterceptor.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerRepository.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerRepository.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerRepository.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerRepository.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerService.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerService.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerService.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/CustomerService.java diff --git a/spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/TwoLevelCacheApplication.java b/spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/TwoLevelCacheApplication.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/java/com/baeldung/caching/twolevelcache/TwoLevelCacheApplication.java rename to spring-boot-modules/spring-boot-caching-2/src/main/java/com/baeldung/caching/twolevelcache/TwoLevelCacheApplication.java diff --git a/spring-boot-modules/spring-caching-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-caching-2/src/main/resources/application.properties similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/resources/application.properties rename to spring-boot-modules/spring-boot-caching-2/src/main/resources/application.properties diff --git a/spring-boot-modules/spring-caching-2/src/main/resources/data.sql b/spring-boot-modules/spring-boot-caching-2/src/main/resources/data.sql similarity index 100% rename from spring-boot-modules/spring-caching-2/src/main/resources/data.sql rename to spring-boot-modules/spring-boot-caching-2/src/main/resources/data.sql diff --git a/spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java b/spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java rename to spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/allkeys/boot/GetAllCacheKeysIntegrationTest.java diff --git a/spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/redis/ItemServiceCachingIntegrationTest.java b/spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/redis/ItemServiceCachingIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/redis/ItemServiceCachingIntegrationTest.java rename to spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/redis/ItemServiceCachingIntegrationTest.java diff --git a/spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/ttl/HotelControllerIntegrationTest.java b/spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/ttl/HotelControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/ttl/HotelControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/ttl/HotelControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/ttl/SlowTest.java b/spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/ttl/SlowTest.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/ttl/SlowTest.java rename to spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/ttl/SlowTest.java diff --git a/spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/twolevelcache/CustomerServiceCachingIntegrationTest.java b/spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/twolevelcache/CustomerServiceCachingIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/java/com/baeldung/caching/twolevelcache/CustomerServiceCachingIntegrationTest.java rename to spring-boot-modules/spring-boot-caching-2/src/test/java/com/baeldung/caching/twolevelcache/CustomerServiceCachingIntegrationTest.java diff --git a/spring-boot-modules/spring-caching-2/src/test/resources/application.properties b/spring-boot-modules/spring-boot-caching-2/src/test/resources/application.properties similarity index 100% rename from spring-boot-modules/spring-caching-2/src/test/resources/application.properties rename to spring-boot-modules/spring-boot-caching-2/src/test/resources/application.properties diff --git a/spring-boot-modules/spring-caching/README.md b/spring-boot-modules/spring-boot-caching/README.md similarity index 89% rename from spring-boot-modules/spring-caching/README.md rename to spring-boot-modules/spring-boot-caching/README.md index e10d6080e8..1690be8f47 100644 --- a/spring-boot-modules/spring-caching/README.md +++ b/spring-boot-modules/spring-boot-caching/README.md @@ -6,3 +6,4 @@ - [Using Multiple Cache Managers in Spring](https://www.baeldung.com/spring-multiple-cache-managers) - [Testing @Cacheable on Spring Data Repositories](https://www.baeldung.com/spring-data-testing-cacheable) - [Spring Boot Ehcache Example](https://www.baeldung.com/spring-boot-ehcache) +- More articles: [[next -->]](/spring-boot-modules/spring-boot-caching-2) \ No newline at end of file diff --git a/spring-boot-modules/spring-caching/pom.xml b/spring-boot-modules/spring-boot-caching/pom.xml similarity index 92% rename from spring-boot-modules/spring-caching/pom.xml rename to spring-boot-modules/spring-boot-caching/pom.xml index 5b4dde6e8b..36fbe6ef27 100644 --- a/spring-boot-modules/spring-caching/pom.xml +++ b/spring-boot-modules/spring-boot-caching/pom.xml @@ -9,10 +9,9 @@ war - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT @@ -49,7 +48,6 @@ com.github.ben-manes.caffeine caffeine - ${caffeine.version} com.h2database diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/Application.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/Application.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/Application.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/Application.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/config/CacheConfig.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/config/CacheConfig.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/config/CacheConfig.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/config/CacheConfig.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/config/CacheEventLogger.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/rest/NumberController.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/rest/NumberController.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/rest/NumberController.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/rest/NumberController.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/service/NumberService.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/service/NumberService.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/cachetest/service/NumberService.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/cachetest/service/NumberService.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/boot/CacheApplication.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/boot/CacheApplication.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/boot/CacheApplication.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/boot/CacheApplication.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/boot/SimpleCacheCustomizer.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/boot/SimpleCacheCustomizer.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/boot/SimpleCacheCustomizer.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/boot/SimpleCacheCustomizer.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/ApplicationCacheConfig.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/ApplicationCacheConfig.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/ApplicationCacheConfig.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/ApplicationCacheConfig.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/CachingConfig.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/CachingConfig.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/CachingConfig.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/CachingConfig.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/CustomKeyGenerator.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/CustomKeyGenerator.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/config/CustomKeyGenerator.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/config/CustomKeyGenerator.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/eviction/controllers/CachingController.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/eviction/controllers/CachingController.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/eviction/controllers/CachingController.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/eviction/controllers/CachingController.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/eviction/service/CachingService.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/eviction/service/CachingService.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/eviction/service/CachingService.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/eviction/service/CachingService.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/AbstractService.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/AbstractService.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/AbstractService.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/AbstractService.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/BookService.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/BookService.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/BookService.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/BookService.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/Customer.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/Customer.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/Customer.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/Customer.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/CustomerDataService.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/CustomerDataService.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/CustomerDataService.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/CustomerDataService.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/CustomerServiceWithParent.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/CustomerServiceWithParent.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/example/CustomerServiceWithParent.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/example/CustomerServiceWithParent.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/model/Book.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/model/Book.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/caching/model/Book.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/caching/model/Book.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/ehcache/calculator/SquaredCalculator.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/ehcache/config/CacheHelper.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/ehcache/config/CacheHelper.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/ehcache/config/CacheHelper.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/ehcache/config/CacheHelper.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/bo/CustomerDetailBO.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/bo/CustomerDetailBO.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/bo/CustomerDetailBO.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/bo/CustomerDetailBO.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/bo/OrderDetailBO.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/bo/OrderDetailBO.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/bo/OrderDetailBO.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/bo/OrderDetailBO.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheManagerConfig.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheManagerConfig.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheManagerConfig.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheManagerConfig.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheResolver.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheResolver.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheResolver.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/config/MultipleCacheResolver.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/controller/MultipleCacheManagerController.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/controller/MultipleCacheManagerController.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/controller/MultipleCacheManagerController.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/controller/MultipleCacheManagerController.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Customer.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Customer.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Customer.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Customer.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Item.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Item.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Item.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Item.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Order.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Order.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Order.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/entity/Order.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/repository/CustomerDetailRepository.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/repository/CustomerDetailRepository.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/repository/CustomerDetailRepository.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/repository/CustomerDetailRepository.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/repository/OrderDetailRepository.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/repository/OrderDetailRepository.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/multiplecachemanager/repository/OrderDetailRepository.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/multiplecachemanager/repository/OrderDetailRepository.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/springdatacaching/model/Book.java diff --git a/spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/repositories/BookRepository.java b/spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/springdatacaching/repositories/BookRepository.java similarity index 100% rename from spring-boot-modules/spring-caching/src/main/java/com/baeldung/springdatacaching/repositories/BookRepository.java rename to spring-boot-modules/spring-boot-caching/src/main/java/com/baeldung/springdatacaching/repositories/BookRepository.java diff --git a/spring-boot-modules/spring-caching/src/main/resources/application.properties b/spring-boot-modules/spring-boot-caching/src/main/resources/application.properties similarity index 100% rename from spring-boot-modules/spring-caching/src/main/resources/application.properties rename to spring-boot-modules/spring-boot-caching/src/main/resources/application.properties diff --git a/spring-boot-modules/spring-caching/src/main/resources/config.xml b/spring-boot-modules/spring-boot-caching/src/main/resources/config.xml similarity index 100% rename from spring-boot-modules/spring-caching/src/main/resources/config.xml rename to spring-boot-modules/spring-boot-caching/src/main/resources/config.xml diff --git a/spring-boot-modules/spring-caching/src/main/resources/data.sql b/spring-boot-modules/spring-boot-caching/src/main/resources/data.sql similarity index 100% rename from spring-boot-modules/spring-caching/src/main/resources/data.sql rename to spring-boot-modules/spring-boot-caching/src/main/resources/data.sql diff --git a/spring-boot-modules/spring-caching/src/main/resources/ehcache.xml b/spring-boot-modules/spring-boot-caching/src/main/resources/ehcache.xml similarity index 100% rename from spring-boot-modules/spring-caching/src/main/resources/ehcache.xml rename to spring-boot-modules/spring-boot-caching/src/main/resources/ehcache.xml diff --git a/dozer/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-caching/src/main/resources/logback.xml similarity index 100% rename from dozer/src/main/resources/logback.xml rename to spring-boot-modules/spring-boot-caching/src/main/resources/logback.xml diff --git a/spring-boot-modules/spring-caching/src/main/resources/schema.sql b/spring-boot-modules/spring-boot-caching/src/main/resources/schema.sql similarity index 100% rename from spring-boot-modules/spring-caching/src/main/resources/schema.sql rename to spring-boot-modules/spring-boot-caching/src/main/resources/schema.sql diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/boot/SimpleCacheCustomizerIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/boot/SimpleCacheCustomizerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/boot/SimpleCacheCustomizerIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/boot/SimpleCacheCustomizerIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/CacheEvictAnnotationIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/CacheEvictAnnotationIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/CacheEvictAnnotationIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/CacheEvictAnnotationIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/CacheManagerEvictIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/CacheManagerEvictIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/CacheManagerEvictIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/CacheManagerEvictIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/SpringCachingIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/SpringCachingIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/caching/test/SpringCachingIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/caching/test/SpringCachingIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/ehcache/SquareCalculatorUnitTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/multiplecachemanager/MultipleCacheManagerIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/multiplecachemanager/MultipleCacheManagerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/multiplecachemanager/MultipleCacheManagerIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/multiplecachemanager/MultipleCacheManagerIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryCachingIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryCachingIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryCachingIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryCachingIntegrationTest.java diff --git a/spring-boot-modules/spring-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryIntegrationTest.java b/spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryIntegrationTest.java rename to spring-boot-modules/spring-boot-caching/src/test/java/com/baeldung/springdatacaching/repositories/BookRepositoryIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-ci-cd/pom.xml b/spring-boot-modules/spring-boot-ci-cd/pom.xml index 6e58f1162d..51adb6bc1b 100644 --- a/spring-boot-modules/spring-boot-ci-cd/pom.xml +++ b/spring-boot-modules/spring-boot-ci-cd/pom.xml @@ -105,7 +105,7 @@ - 0.8.5 + 0.8.11 3.0.2 2.2.0 diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml index d7f437633d..96cfd622db 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -42,6 +42,12 @@ ${spring-boot.version} test + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + test + @@ -61,6 +67,7 @@ 2.2.6.RELEASE 0.0.1-SNAPSHOT + 1.14.13 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/pom.xml b/spring-boot-modules/spring-boot-data-3/pom.xml index 0d35da3a0a..c6cd426bb2 100644 --- a/spring-boot-modules/spring-boot-data-3/pom.xml +++ b/spring-boot-modules/spring-boot-data-3/pom.xml @@ -10,10 +10,9 @@ spring-boot-data-3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-di/src/test/java/com/baeldung/displayallbeans/DisplayBeanIntegrationTest.java b/spring-boot-modules/spring-boot-di/src/test/java/com/baeldung/displayallbeans/DisplayBeanIntegrationTest.java index f08a755fc7..4e157e4e13 100644 --- a/spring-boot-modules/spring-boot-di/src/test/java/com/baeldung/displayallbeans/DisplayBeanIntegrationTest.java +++ b/spring-boot-modules/spring-boot-di/src/test/java/com/baeldung/displayallbeans/DisplayBeanIntegrationTest.java @@ -13,10 +13,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.actuate.beans.BeansEndpoint.ContextBeans; +import org.springframework.boot.actuate.beans.BeansEndpoint.ContextBeansDescriptor; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -54,12 +54,12 @@ public class DisplayBeanIntegrationTest { @Test public void givenRestTemplate_whenAccessEndpointUrl_thenHttpStatusOK() throws Exception { - ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() { + ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() { }; RequestEntity requestEntity = RequestEntity.get(new URI("http://localhost:" + this.mgt + ACTUATOR_PATH + "/beans")) .accept(MediaType.APPLICATION_JSON) .build(); - ResponseEntity> entity = this.testRestTemplate.exchange(requestEntity, responseType); + ResponseEntity> entity = this.testRestTemplate.exchange(requestEntity, responseType); then(entity.getStatusCode()).isEqualTo(HttpStatus.OK); } diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml index 677e07db2d..b03bc3b004 100644 --- a/spring-boot-modules/spring-boot-groovy/pom.xml +++ b/spring-boot-modules/spring-boot-groovy/pom.xml @@ -10,10 +10,9 @@ Spring Boot Todo Application with Groovy - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-libraries-3/pom.xml b/spring-boot-modules/spring-boot-libraries-3/pom.xml index 988ce0bafe..223a39f1de 100644 --- a/spring-boot-modules/spring-boot-libraries-3/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-3/pom.xml @@ -6,10 +6,9 @@ spring-boot-libraries-3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT @@ -17,7 +16,6 @@ org.springframework.boot spring-boot-starter-data-jpa - org.springframework.kafka spring-kafka @@ -28,20 +26,27 @@ postgresql ${postgresql.version} + org.springframework.modulith spring-modulith-events-api - ${spring-modulith-events-kafka.version} + ${spring-modulith.version} org.springframework.modulith spring-modulith-events-kafka - ${spring-modulith-events-kafka.version} + ${spring-modulith.version} org.springframework.modulith spring-modulith-starter-jpa - ${spring-modulith-events-kafka.version} + ${spring-modulith.version} + + + org.springframework.modulith + spring-modulith-starter-test + ${spring-modulith.version} + test @@ -54,7 +59,6 @@ spring-boot-testcontainers test - org.testcontainers kafka @@ -73,7 +77,6 @@ ${testcontainers.version} test - org.testcontainers postgresql @@ -87,16 +90,23 @@ ${awaitility.version} test + + com.h2database + h2 + ${h2.version} + test + 17 3.1.5 - 1.1.2 + 1.1.3 1.19.3 4.2.0 42.3.1 + 2.2.224 diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/Order.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/Order.java new file mode 100644 index 0000000000..c448bd44dd --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/Order.java @@ -0,0 +1,12 @@ +package com.baeldung.springmodulith.application.events.orders; + +import java.time.Instant; +import java.util.List; + +record Order(String id, String customerId, List productIds, Instant timestamp) { + + public Order(String customerId, List productIds) { + this(null, customerId, productIds, Instant.now()); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderCompletedEvent.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderCompletedEvent.java new file mode 100644 index 0000000000..4344b336ac --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderCompletedEvent.java @@ -0,0 +1,6 @@ +package com.baeldung.springmodulith.application.events.orders; + +import java.time.Instant; + +public record OrderCompletedEvent(String orderId, String customerId, Instant timestamp) { +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderRepository.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderRepository.java new file mode 100644 index 0000000000..7c159e3582 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderRepository.java @@ -0,0 +1,27 @@ +package com.baeldung.springmodulith.application.events.orders; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.springframework.stereotype.Component; + +@Component +class OrderRepository { + private final List orders = new ArrayList<>(); + + public Order save(Order order) { + order = new Order(UUID.randomUUID() + .toString(), order.customerId(), order.productIds(), order.timestamp()); + orders.add(order); + return order; + } + + public List ordersByCustomer(String customerId) { + return orders.stream() + .filter(it -> it.customerId() + .equals(customerId)) + .toList(); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderService.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderService.java new file mode 100644 index 0000000000..c60792813c --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/orders/OrderService.java @@ -0,0 +1,29 @@ +package com.baeldung.springmodulith.application.events.orders; + +import java.util.Arrays; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +public class OrderService { + + private final OrderRepository repository; + private final ApplicationEventPublisher eventPublisher; + + public OrderService(OrderRepository orders, ApplicationEventPublisher eventsPublisher) { + this.repository = orders; + this.eventPublisher = eventsPublisher; + } + + public void placeOrder(String customerId, String... productIds) { + Order order = new Order(customerId, Arrays.asList(productIds)); + // business logic to validate and place the order + + Order savedOrder = repository.save(order); + + OrderCompletedEvent event = new OrderCompletedEvent(savedOrder.id(), savedOrder.customerId(), savedOrder.timestamp()); + eventPublisher.publishEvent(event); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyalCustomersRepository.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyalCustomersRepository.java new file mode 100644 index 0000000000..29ba6fa8e2 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyalCustomersRepository.java @@ -0,0 +1,44 @@ +package com.baeldung.springmodulith.application.events.rewards; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Component; + +@Component +public class LoyalCustomersRepository { + + private List customers = new ArrayList<>(); + + public Optional find(String customerId) { + return customers.stream() + .filter(it -> it.customerId() + .equals(customerId)) + .findFirst(); + } + + public void awardPoints(String customerId, int points) { + var customer = find(customerId).orElseGet(() -> save(new LoyalCustomer(customerId, 0))); + + customers.remove(customer); + customers.add(customer.addPoints(points)); + } + + public LoyalCustomer save(LoyalCustomer customer) { + customers.add(customer); + return customer; + } + + public boolean isLoyalCustomer(String customerId) { + return find(customerId).isPresent(); + } + + public record LoyalCustomer(String customerId, int points) { + + LoyalCustomer addPoints(int points) { + return new LoyalCustomer(customerId, this.points() + points); + } + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyaltyPointsService.java b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyaltyPointsService.java new file mode 100644 index 0000000000..8cd1afe329 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/main/java/com/baeldung/springmodulith/application/events/rewards/LoyaltyPointsService.java @@ -0,0 +1,24 @@ +package com.baeldung.springmodulith.application.events.rewards; + +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +import com.baeldung.springmodulith.application.events.orders.OrderCompletedEvent; + +@Service +public class LoyaltyPointsService { + + public static final int ORDER_COMPLETED_POINTS = 60; + private final LoyalCustomersRepository loyalCustomers; + + public LoyaltyPointsService(LoyalCustomersRepository loyalCustomers) { + this.loyalCustomers = loyalCustomers; + } + + @EventListener + public void onOrderCompleted(OrderCompletedEvent event) { + // business logic to award points to loyal customers + loyalCustomers.awardPoints(event.customerId(), ORDER_COMPLETED_POINTS); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventListenerUnitTest.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventListenerUnitTest.java new file mode 100644 index 0000000000..676bc1173b --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventListenerUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.springmodulith.application.events; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationEventPublisher; + +import com.baeldung.springmodulith.application.events.orders.OrderCompletedEvent; +import com.baeldung.springmodulith.application.events.rewards.LoyalCustomersRepository; + +@SpringBootTest +class EventListenerUnitTest { + + @Autowired + private LoyalCustomersRepository customers; + + @Autowired + private ApplicationEventPublisher testEventPublisher; + + @Test + void whenPublishingOrderCompletedEvent_thenRewardCustomerWithLoyaltyPoints() { + OrderCompletedEvent event = new OrderCompletedEvent("order-1", "customer-1", Instant.now()); + + testEventPublisher.publishEvent(event); + + assertThat(customers.find("customer-1")) + .isPresent().get() + .hasFieldOrPropertyWithValue("customerId", "customer-1") + .hasFieldOrPropertyWithValue("points", 60); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventPublisherUnitTest.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventPublisherUnitTest.java new file mode 100644 index 0000000000..f4bdeee90d --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/EventPublisherUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.springmodulith.application.events; + +import com.baeldung.springmodulith.application.events.orders.OrderService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +class EventPublisherUnitTest { + + @Autowired + OrderService orderService; + + @Autowired + TestEventListener testEventListener; + + @BeforeEach + void beforeEach() { + testEventListener.reset(); + } + + @Test + void whenPlacingOrder_thenPublishApplicationEvent() { + orderService.placeOrder("customer1", "product1", "product2"); + + assertThat(testEventListener.getEvents()) + .hasSize(1).first() + .hasFieldOrPropertyWithValue("customerId", "customer1") + .hasFieldOrProperty("orderId") + .hasFieldOrProperty("timestamp"); + } + +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/SpringModulithScenarioApiUnitTest.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/SpringModulithScenarioApiUnitTest.java new file mode 100644 index 0000000000..f36a0c30e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/SpringModulithScenarioApiUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.springmodulith.application.events; + +import com.baeldung.springmodulith.application.events.orders.OrderCompletedEvent; +import com.baeldung.springmodulith.application.events.orders.OrderService; +import com.baeldung.springmodulith.application.events.rewards.LoyalCustomersRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.modulith.test.ApplicationModuleTest; +import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode; +import org.springframework.modulith.test.Scenario; + +import java.time.Duration; +import java.time.Instant; + +import static java.time.Duration.ofMillis; +import static org.assertj.core.api.Assertions.assertThat; + +@ApplicationModuleTest +class SpringModulithScenarioApiUnitTest { + + @Autowired + OrderService orderService; + + @Autowired + LoyalCustomersRepository loyalCustomers; + + @Test + void whenPlacingOrder_thenPublishOrderCompletedEvent(Scenario scenario) { + scenario.stimulate(() -> orderService.placeOrder("customer-1", "product-1", "product-2")) + .andWaitForEventOfType(OrderCompletedEvent.class) + .toArriveAndVerify(evt -> assertThat(evt) + .hasFieldOrPropertyWithValue("customerId", "customer-1") + .hasFieldOrProperty("orderId") + .hasFieldOrProperty("timestamp")); + } + + @Test + void whenReceivingPublishOrderCompletedEvent_thenRewardCustomerWithLoyaltyPoints(Scenario scenario) { + scenario.publish(new OrderCompletedEvent("order-1", "customer-1", Instant.now())) + .andWaitForStateChange(() -> loyalCustomers.find("customer-1")) + .andVerify(it -> assertThat(it) + .isPresent().get() + .hasFieldOrPropertyWithValue("customerId", "customer-1") + .hasFieldOrPropertyWithValue("points", 60)); + } +} diff --git a/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/TestEventListener.java b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/TestEventListener.java new file mode 100644 index 0000000000..8973a99355 --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries-3/src/test/java/com/baeldung/springmodulith/application/events/TestEventListener.java @@ -0,0 +1,29 @@ +package com.baeldung.springmodulith.application.events; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import com.baeldung.springmodulith.application.events.orders.OrderCompletedEvent; + +@Component +class TestEventListener { + + private final List events = new ArrayList<>(); + + @EventListener + void onEvent(OrderCompletedEvent event) { + events.add(event); + } + + public List getEvents() { + return events; + } + + public void reset() { + events.clear(); + } +} + diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java index 171d703621..a1318c0519 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java @@ -4,10 +4,17 @@ import com.baeldung.barcodes.generators.BarbecueBarcodeGenerator; import com.baeldung.barcodes.generators.Barcode4jBarcodeGenerator; import com.baeldung.barcodes.generators.QRGenBarcodeGenerator; import com.baeldung.barcodes.generators.ZxingBarcodeGenerator; +import com.baeldung.barcodes.generators.ZxingBarcodeGeneratorWithText; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import java.awt.image.BufferedImage; @@ -76,6 +83,11 @@ public class BarcodesController { return okResponse(ZxingBarcodeGenerator.generateCode128BarcodeImage(barcode)); } + @GetMapping(value = "/zxing/qrcode/text", produces = MediaType.IMAGE_PNG_VALUE) + public ResponseEntity zxingCodeQRcodeText(@RequestParam("barcode") String barcode, @RequestParam("toptext") String toptext, @RequestParam("bottomtext") String bottomtext) throws Exception { + return okResponse(ZxingBarcodeGeneratorWithText.createQRwithText(barcode, toptext, bottomtext)); + } + @PostMapping(value = "/zxing/pdf417", produces = MediaType.IMAGE_PNG_VALUE) public ResponseEntity zxingPDF417Barcode(@RequestBody String barcode) throws Exception { return okResponse(ZxingBarcodeGenerator.generatePDF417BarcodeImage(barcode)); diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java new file mode 100644 index 0000000000..e6ebcf9bae --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java @@ -0,0 +1,59 @@ +package com.baeldung.barcodes.generators; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +import java.awt.Graphics2D; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.image.BufferedImage; +import java.io.IOException; + +public class ZxingBarcodeGeneratorWithText { + + public static BufferedImage createQRwithText(String data, String topText, String bottomText) throws WriterException, IOException { + QRCodeWriter barcodeWriter = new QRCodeWriter(); + BitMatrix matrix = barcodeWriter.encode(data, BarcodeFormat.QR_CODE, 200, 200); + return modifiedQRCode(matrix, topText, bottomText); + } + + public static BufferedImage modifiedQRCode(BitMatrix matrix, String topText, String bottomText) throws IOException { + int matrixWidth = matrix.getWidth(); + int matrixHeight = matrix.getHeight(); + + BufferedImage image = new BufferedImage(matrixWidth, matrixHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D graphics = image.createGraphics(); + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, matrixWidth, matrixHeight); + graphics.setColor(Color.BLACK); + + for (int i = 0; i < matrixWidth; i++) { + for (int j = 0; j < matrixHeight; j++) { + if (matrix.get(i, j)) { + graphics.fillRect(i, j, 1, 1); + } + } + } + + FontMetrics fontMetrics = graphics.getFontMetrics(); + int topTextWidth = fontMetrics.stringWidth(topText); + int bottomTextWidth = fontMetrics.stringWidth(bottomText); + int finalWidth = Math.max(matrixWidth, Math.max(topTextWidth, bottomTextWidth)) + 1; + int finalHeight = matrixHeight + fontMetrics.getHeight() + fontMetrics.getAscent() + 1; + + BufferedImage finalImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D finalGraphics = finalImage.createGraphics(); + finalGraphics.setColor(Color.WHITE); + finalGraphics.fillRect(0, 0, finalWidth, finalHeight); + finalGraphics.setColor(Color.BLACK); + + finalGraphics.drawImage(image, (finalWidth - matrixWidth) / 2, fontMetrics.getAscent() + 2, null); + finalGraphics.drawString(topText, (finalWidth - topTextWidth) / 2, fontMetrics.getAscent() + 2); + finalGraphics.drawString(bottomText, (finalWidth - bottomTextWidth) / 2, finalHeight - fontMetrics.getDescent() - 2); + + return finalImage; + } + +} diff --git a/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java new file mode 100644 index 0000000000..6f1ffe4730 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java @@ -0,0 +1,11 @@ +package com.baeldung.logging; + +import org.springframework.stereotype.Component; + +@Component +public class LogbackConfiguration { + public void setLogbackConfigurationFile(String path) { + System.setProperty("logback.configurationFile", path); + } +} + diff --git a/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java new file mode 100644 index 0000000000..006305cac0 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.logging; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {LogbackConfiguration.class}) +public class LogbackConfigurationUnitTest { + + @Autowired + LogbackConfiguration logbackConfiguration; + + @Test + public void givenLogbackConfigurationFile_whenSettingLogbackConfiguration_thenFileLocationSet() { + // Set the expected logback.xml location + String expectedLocation = "/test/path/to/logback.xml"; + // Call the method to set the logback configuration file + logbackConfiguration.setLogbackConfigurationFile(expectedLocation); + // Verify that the system property is correctly set + assertThat(System.getProperty("logback.configurationFile")).isEqualTo(expectedLocation); + } +} diff --git a/spring-boot-modules/spring-boot-logging-loki/README.md b/spring-boot-modules/spring-boot-logging-loki/README.md new file mode 100644 index 0000000000..376f9d803f --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-loki/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Logging in Spring Boot With Loki](https://www.baeldung.com/spring-boot-loki-grafana-logging) diff --git a/spring-boot-modules/spring-boot-logging-loki/pom.xml b/spring-boot-modules/spring-boot-logging-loki/pom.xml new file mode 100644 index 0000000000..5b2887562b --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-loki/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + spring-boot-logging-loki + 0.1-SNAPSHOT + loki + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + com.github.loki4j + loki-logback-appender + ${loki-logback.version} + + + org.springframework.boot + spring-boot-starter-test + + + org.springframework.boot + spring-boot-starter-web + + + + + 1.4.2 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-logging-loki/src/main/java/com/baeldung/loki/DemoService.java b/spring-boot-modules/spring-boot-logging-loki/src/main/java/com/baeldung/loki/DemoService.java new file mode 100644 index 0000000000..89fdcc48e8 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-loki/src/main/java/com/baeldung/loki/DemoService.java @@ -0,0 +1,15 @@ +package com.baeldung.loki; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class DemoService { + + private static final Logger LOG = LoggerFactory.getLogger(DemoService.class); + + public void log() { + LOG.info("DemoService.log invoked"); + } +} diff --git a/spring-boot-modules/spring-boot-logging-loki/src/main/resources/logback-spring.xml b/spring-boot-modules/spring-boot-logging-loki/src/main/resources/logback-spring.xml new file mode 100644 index 0000000000..1ba53d7278 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-loki/src/main/resources/logback-spring.xml @@ -0,0 +1,32 @@ + + + + + + + http://localhost:3100/loki/api/v1/push + + + + + + { + "level":"%level", + "class":"%logger{36}", + "thread":"%thread", + "message": "%message", + "requestId": "%X{X-Request-ID}" + } + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-logging-loki/src/test/java/com/baeldung/loki/DemoServiceLiveTest.java b/spring-boot-modules/spring-boot-logging-loki/src/test/java/com/baeldung/loki/DemoServiceLiveTest.java new file mode 100644 index 0000000000..4c44888dca --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-loki/src/test/java/com/baeldung/loki/DemoServiceLiveTest.java @@ -0,0 +1,85 @@ +package com.baeldung.loki; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.net.URI; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +@SpringBootTest(classes = DemoService.class) +public class DemoServiceLiveTest { + + /** + * This test assumes that loki service is already up. + * For more details please check section #2 Running Loki and Grafana Service + * Which spin up Loki server using docker-compose + */ + @Test + public void givenLokiContainerRunning_whenDemoServiceInvoked_thenLokiAppenderCollectLogs() throws JsonProcessingException, InterruptedException { + DemoService service = new DemoService(); + service.log(); + + String baseUrl = "http://localhost:3100/loki/api/v1/query_range"; + // Set up query parameters + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + String query = "{level=\"INFO\"} |= `DemoService.log invoked`"; + + // Get current time in UTC + LocalDateTime currentDateTime = LocalDateTime.now(ZoneOffset.UTC); + String currentTimeUtc = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")); + + LocalDateTime tenMinsAgo = currentDateTime.minusMinutes(10); + String startTimeUtc = tenMinsAgo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")); + + URI uri = UriComponentsBuilder.fromUriString(baseUrl) + .queryParam("query", query) + .queryParam("start", startTimeUtc) + .queryParam("end", currentTimeUtc) + .build() + .toUri(); + + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.exchange(uri, HttpMethod.GET, new HttpEntity<>(headers), String.class); + + List messages = new ArrayList<>(); + ObjectMapper objectMapper = new ObjectMapper(); + assertEquals(response.getStatusCode(), HttpStatus.OK); + + String responseBody = response.getBody(); + JsonNode jsonNode = objectMapper.readTree(responseBody); + JsonNode result = jsonNode.get("data") + .get("result") + .get(0) + .get("values"); + result.iterator() + .forEachRemaining(e -> { + Iterator elements = e.elements(); + elements.forEachRemaining(f -> messages.add(f.toString())); + }); + + String expected = "DemoService.log invoked"; + assertThat(messages).anyMatch(e -> e.contains(expected)); + } +} diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index ab1c867d66..ec084df714 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -52,8 +52,8 @@ org.glassfish - javax.faces - ${javax.faces.version} + jakarta.faces + ${jakarta.faces.version} @@ -73,8 +73,9 @@ hibernate-validator - javax.validation - validation-api + jakarta.validation + jakarta.validation-api + ${jakarta.validation-api.version} org.springframework.boot @@ -112,8 +113,9 @@ 1.10.0 - 2.3.7 + 4.1.0-M1 1.9.20.1 + 3.1.0-M1 com.baeldung.springbootmvc.SpringBootMvcApplication diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java index b1bdc7d781..049fcc986f 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java @@ -1,8 +1,8 @@ package com.baeldung.annotation.servletcomponentscan.components; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.annotation.WebListener; @WebListener public class AttrListener implements ServletContextListener { diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java index d8192c2cb1..89b948ba87 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java @@ -1,9 +1,10 @@ package com.baeldung.annotation.servletcomponentscan.components; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import java.io.File; import java.io.IOException; import java.nio.file.Files; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java index 146e5ae386..f6472174a2 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java @@ -1,8 +1,9 @@ package com.baeldung.annotation.servletcomponentscan.components; -import javax.servlet.*; -import javax.servlet.annotation.WebFilter; -import javax.servlet.annotation.WebInitParam; +import jakarta.servlet.*; +import jakarta.servlet.annotation.WebFilter; +import jakarta.servlet.annotation.WebInitParam; + import java.io.IOException; @WebFilter(urlPatterns = "/hello", description = "a filter for hello servlet", initParams = { @WebInitParam(name = "msg", value = "filtering ") }, filterName = "hello filter", servletNames = { "echo servlet" }) diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java index 5269c1bf29..8caa798e76 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java @@ -1,11 +1,12 @@ package com.baeldung.annotation.servletcomponentscan.components; -import javax.servlet.ServletConfig; -import javax.servlet.annotation.WebInitParam; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.annotation.WebInitParam; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; @WebServlet(urlPatterns = "/hello", initParams = { @WebInitParam(name = "msg", value = "hello") }) diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/internationalization/InternationalizationApp.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/internationalization/InternationalizationApp.java index c3af611f3b..2fdd79d060 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/internationalization/InternationalizationApp.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/internationalization/InternationalizationApp.java @@ -1,7 +1,7 @@ package com.baeldung.internationalization; -import javax.annotation.security.RolesAllowed; +import jakarta.annotation.security.RolesAllowed; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/responseentity/CustomResponseController.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/responseentity/CustomResponseController.java index 098c5e4794..19246e3014 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/responseentity/CustomResponseController.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/responseentity/CustomResponseController.java @@ -3,8 +3,7 @@ package com.baeldung.responseentity; import java.io.IOException; import java.time.Year; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java index e37e2c9d78..c0bfd641d4 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/MessageConfig.java @@ -1,7 +1,6 @@ package com.baeldung.restvalidation.config; -import javax.validation.MessageInterpolator; - +import jakarta.validation.MessageInterpolator; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java index 003a3d79b0..a81c19148a 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/config/RecursiveLocaleContextMessageInterpolator.java @@ -4,8 +4,7 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.validation.MessageInterpolator; - +import jakarta.validation.MessageInterpolator; import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java index f9a7d1a9b5..eff81f6dda 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/User.java @@ -1,7 +1,6 @@ package com.baeldung.restvalidation.service1; -import javax.validation.constraints.NotEmpty; - +import jakarta.validation.constraints.NotEmpty; import lombok.*; @Data diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java index 790b5031e6..6883e539f8 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service1/UserService1.java @@ -1,5 +1,6 @@ package com.baeldung.restvalidation.service1; +import jakarta.validation.Valid; import org.springframework.http.*; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; @@ -7,8 +8,6 @@ import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.stream.Collectors; -import javax.validation.Valid; - import com.baeldung.restvalidation.response.InputFieldError; import com.baeldung.restvalidation.response.UpdateUserResponse; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java index a2e567766c..dd9584e27b 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/User.java @@ -1,7 +1,6 @@ package com.baeldung.restvalidation.service2; -import javax.validation.constraints.NotEmpty; - +import jakarta.validation.constraints.NotEmpty; import lombok.*; @Data diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java index 4593a2b1bd..78ec60720d 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service2/UserService2.java @@ -3,8 +3,7 @@ package com.baeldung.restvalidation.service2; import java.util.List; import java.util.stream.Collectors; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java index 93c7052d5b..03392af45c 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmpty.java @@ -1,5 +1,8 @@ package com.baeldung.restvalidation.service3; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; @@ -12,8 +15,6 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; @Documented @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java index 356efc590b..5d4b188911 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/FieldNotEmptyValidator.java @@ -1,7 +1,7 @@ package com.baeldung.restvalidation.service3; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; public class FieldNotEmptyValidator implements ConstraintValidator { diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java index e506b63d8e..3efb88c29d 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/restvalidation/service3/UserService3.java @@ -3,8 +3,7 @@ package com.baeldung.restvalidation.service3; import java.util.List; import java.util.stream.Collectors; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java index c9b9c51bec..8cfb9b9931 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java @@ -6,9 +6,8 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.view.feed.AbstractRssFeedView; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootannotations/MySQLAutoconfiguration.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootannotations/MySQLAutoconfiguration.java index 62b1329a54..d3d3cb44d5 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootannotations/MySQLAutoconfiguration.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootannotations/MySQLAutoconfiguration.java @@ -3,9 +3,9 @@ package com.baeldung.springbootannotations; import java.util.Arrays; import java.util.Properties; -import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; +import jakarta.persistence.EntityManagerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionMessage; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java index 589024c0bc..190e882781 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java @@ -1,7 +1,6 @@ package com.baeldung.springbootmvc; -import javax.validation.Valid; - +import jakarta.validation.Valid; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java index 5b4250d5e3..86265b0b4d 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java @@ -1,7 +1,6 @@ package com.baeldung.springbootmvc.jsfapplication; -import javax.faces.webapp.FacesServlet; - +import jakarta.faces.webapp.FacesServlet; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletRegistrationBean; diff --git a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java index 107cd1bbf1..274265e97b 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java +++ b/spring-boot-modules/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java @@ -1,8 +1,8 @@ package com.baeldung.springbootmvc.model; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; public class LoginForm { diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties index 90d3c88a8f..f8e1a6a434 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages.properties @@ -1 +1 @@ -javax.validation.constraints.NotEmpty.message=The field cannot be empty \ No newline at end of file +jakarta.validation.constraints.NotEmpty.message=The field cannot be empty \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties index 04f415911c..5c7bfbcb36 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties +++ b/spring-boot-modules/spring-boot-mvc/src/main/resources/ValidationMessages_zh.properties @@ -1 +1 @@ -javax.validation.constraints.NotEmpty.message=本欄不能留空 \ No newline at end of file +jakarta.validation.constraints.NotEmpty.message=本欄不能留空 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml b/spring-boot-modules/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml index e0cd4d8850..45d30565fe 100644 --- a/spring-boot-modules/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml +++ b/spring-boot-modules/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml @@ -7,7 +7,7 @@ Faces Servlet - javax.faces.webapp.FacesServlet + jakarta.faces.webapp.FacesServlet 1 diff --git a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java index 92223892d9..230fe200e6 100644 --- a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java +++ b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java @@ -4,9 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import javax.servlet.FilterRegistration; -import javax.servlet.ServletContext; - +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.ServletContext; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java index c29cd75e9d..0d413be91e 100644 --- a/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java +++ b/spring-boot-modules/spring-boot-mvc/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java @@ -4,9 +4,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import javax.servlet.FilterRegistration; -import javax.servlet.ServletContext; - +import jakarta.servlet.FilterRegistration; +import jakarta.servlet.ServletContext; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/config/RedisTestConfiguration.java b/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/config/RedisTestConfiguration.java index 6fbd140981..8f59c5bd65 100644 --- a/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/config/RedisTestConfiguration.java +++ b/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/config/RedisTestConfiguration.java @@ -13,6 +13,11 @@ public class RedisTestConfiguration { public RedisTestConfiguration(RedisProperties redisProperties) { this.redisServer = new RedisServer(redisProperties.getPort()); + // To run on windows uncomment the following lines + // this.redisServer = RedisServer.builder().setting("maxheap 200m") + // .port(redisProperties.getPort()) + // .setting("bind localhost") + // .build(); } @PostConstruct diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 668c9d561f..20dec5410c 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -30,6 +30,11 @@ springdoc-openapi-ui ${springdoc.version} + + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api.version} + @@ -82,6 +87,8 @@ 3.1.1 1.7.0 + 3.1.0 + com.baeldung.swaggerexample.SwaggerExampleApplication \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerenums/controller/HireController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerenums/controller/HireController.java index 7b7bfdc2c5..9b142d3802 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerenums/controller/HireController.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerenums/controller/HireController.java @@ -5,9 +5,9 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; @Api @Path(value="/hire") diff --git a/spring-boot-modules/spring-boot-telegram/baeldungbot b/spring-boot-modules/spring-boot-telegram/baeldungbot deleted file mode 100644 index 75faf49e5e..0000000000 Binary files a/spring-boot-modules/spring-boot-telegram/baeldungbot and /dev/null differ diff --git a/spring-boot-modules/spring-caching-3/README.md b/spring-boot-modules/spring-caching-3/README.md new file mode 100644 index 0000000000..2e33ad3c6c --- /dev/null +++ b/spring-boot-modules/spring-caching-3/README.md @@ -0,0 +1,3 @@ +## Relevant articles + +- [Disable @Cacheable in Spring Boot](https://www.baeldung.com/spring-boot-disable-cacheable-annotation) diff --git a/spring-boot-modules/spring-caching-3/pom.xml b/spring-boot-modules/spring-caching-3/pom.xml new file mode 100644 index 0000000000..dcdf886502 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/pom.xml @@ -0,0 +1,44 @@ + + + 4.0.0 + spring-caching-3 + 0.1-SNAPSHOT + spring-caching-3 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + jar + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookRepository.java b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookRepository.java new file mode 100644 index 0000000000..07898aa090 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.caching.disable; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BookRepository extends JpaRepository { + + List findByIsbn(String isbn); +} diff --git a/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReview.java b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReview.java new file mode 100644 index 0000000000..210cdb0d8a --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReview.java @@ -0,0 +1,70 @@ +package com.baeldung.caching.disable; + +import jakarta.persistence.*; + +import java.util.Objects; + +@Entity +@Table(name = "BOOK_REVIEWS") +public class BookReview { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_reviews_reviews_id_seq") + @SequenceGenerator(name = "book_reviews_reviews_id_seq", sequenceName = "book_reviews_reviews_id_seq", allocationSize = 1) + private Long reviewsId; + private String userId; + private String isbn; + private String bookRating; + + public Long getReviewsId() { + return reviewsId; + } + + public void setReviewsId(Long reviewsId) { + this.reviewsId = reviewsId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getBookRating() { + return bookRating; + } + + public void setBookRating(String bookRating) { + this.bookRating = bookRating; + } + + @Override + public String toString() { + return "BookReview{" + "reviewsId=" + reviewsId + ", userId='" + userId + '\'' + ", isbn='" + isbn + '\'' + ", bookRating='" + bookRating + '\'' + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + BookReview that = (BookReview) o; + return Objects.equals(reviewsId, that.reviewsId) && Objects.equals(userId, that.userId) && Objects.equals(isbn, that.isbn) && Objects.equals(bookRating, that.bookRating); + } + + @Override + public int hashCode() { + return Objects.hash(reviewsId, userId, isbn, bookRating); + } +} diff --git a/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewApplication.java b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewApplication.java new file mode 100644 index 0000000000..c035424632 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.caching.disable; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; + +@SpringBootApplication +@EnableCaching +@EnableAutoConfiguration +public class BookReviewApplication { + public static void main(String[] args) { + SpringApplication.run(BookReviewApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewsLogic.java b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewsLogic.java new file mode 100644 index 0000000000..1af8cdf4ab --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/BookReviewsLogic.java @@ -0,0 +1,25 @@ +package com.baeldung.caching.disable; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +@Service +public class BookReviewsLogic { + + @Autowired + private BookRepository bookRepository; + + @Autowired + private CacheManager cacheManager; + + @Cacheable(value = "book_reviews", key = "#isbn") + public List getBooksByIsbn(String isbn) { + return bookRepository.findByIsbn(isbn); + } +} diff --git a/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/CacheConfig.java b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/CacheConfig.java new file mode 100644 index 0000000000..23f90370f5 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/java/com/baeldung/caching/disable/CacheConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.caching.disable; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.cache.support.NoOpCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableCaching +public class CacheConfig { + + @Bean + public CacheManager cacheManager(@Value("${appconfig.cache.enabled}") String isCacheEnabled) { + if (isCacheEnabled.equalsIgnoreCase("false")) { + return new NoOpCacheManager(); + } + + return new ConcurrentMapCacheManager(); + } +} diff --git a/spring-boot-modules/spring-caching-3/src/main/resources/application.properties b/spring-boot-modules/spring-caching-3/src/main/resources/application.properties new file mode 100644 index 0000000000..f3c5e31283 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/main/resources/application.properties @@ -0,0 +1,9 @@ +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= +# Enabling H2 Console +spring.h2.console.enabled=true +spring.h2.console.path=/h2 +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true diff --git a/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicCacheDisabledUnitTest.java b/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicCacheDisabledUnitTest.java new file mode 100644 index 0000000000..34f1052363 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicCacheDisabledUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.caching.disable; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = BookReviewApplication.class) +@ExtendWith(OutputCaptureExtension.class) +@TestPropertySource(properties = { + "appconfig.cache.enabled=false" +}) +public class BookReviewsLogicCacheDisabledUnitTest { + + @Autowired + private BookReviewsLogic bookReviewsLogic; + + @Autowired + private BookRepository bookRepository; + + @Test + public void givenCacheDisabled_whenLogicExecuted2ndTime_thenItQueriesDB(CapturedOutput output){ + BookReview bookReview = insertBookReview(); + + bookReviewsLogic.getBooksByIsbn(bookReview.getIsbn()); + + String target = "Hibernate: select b1_0.reviews_id," + + "b1_0.book_rating,b1_0.isbn,b1_0.user_id " + + "from book_reviews b1_0 " + + "where b1_0.isbn=?"; + + String[] logs = output.toString() + .split("\\r?\\n"); + assertThat(logs).anyMatch(e -> e.contains(target)); + + bookReviewsLogic.getBooksByIsbn(bookReview.getIsbn()); + logs = output.toString() + .split("\\r?\\n"); + + long count = Arrays.stream(logs) + .filter(e -> e.contains(target)) + .count(); + + // count 2 means the select query log from 1st and 2nd execution. + assertEquals(2, count); + } + + private BookReview insertBookReview() { + BookReview bookReview = new BookReview(); + bookReview.setReviewsId(123L); + bookReview.setBookRating("3.2"); + bookReview.setUserId("111"); + bookReview.setIsbn("1234"); + bookRepository.save(bookReview); + return bookReview; + } +} diff --git a/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicUnitTest.java b/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicUnitTest.java new file mode 100644 index 0000000000..8b1b2faa49 --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/test/java/com/baeldung/caching/disable/BookReviewsLogicUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.caching.disable; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = BookReviewApplication.class) +@ExtendWith(OutputCaptureExtension.class) +public class BookReviewsLogicUnitTest { + + @Autowired + private BookReviewsLogic bookReviewsLogic; + + @Autowired + private BookRepository bookRepository; + + @Test + public void givenCacheEnabled_whenLogicExecuted2ndTime_thenItDoesntQueriesDB(CapturedOutput output){ + BookReview bookReview = insertBookReview(); + + String target = "Hibernate: select b1_0.reviews_id," + + "b1_0.book_rating,b1_0.isbn,b1_0.user_id " + + "from book_reviews b1_0 " + + "where b1_0.isbn=?"; + + // 1st execution + bookReviewsLogic.getBooksByIsbn(bookReview.getIsbn()); + String[] logs = output.toString() + .split("\\r?\\n"); + assertThat(logs).anyMatch(e -> e.contains(target)); + + // 2nd execution + bookReviewsLogic.getBooksByIsbn(bookReview.getIsbn()); + logs = output.toString() + .split("\\r?\\n"); + System.out.println(logs); + long count = Arrays.stream(logs) + .filter(e -> e.equals(target)) + .count(); + + // count 1 means the select query log from 1st execution. + assertEquals(1,count); + } + + private BookReview insertBookReview() { + BookReview bookReview = new BookReview(); + bookReview.setReviewsId(123L); + bookReview.setBookRating("3.2"); + bookReview.setUserId("111"); + bookReview.setIsbn("1234"); + bookRepository.save(bookReview); + return bookReview; + } +} diff --git a/spring-boot-modules/spring-caching-3/src/test/resources/application.properties b/spring-boot-modules/spring-caching-3/src/test/resources/application.properties new file mode 100644 index 0000000000..c62237927f --- /dev/null +++ b/spring-boot-modules/spring-caching-3/src/test/resources/application.properties @@ -0,0 +1,12 @@ +appconfig.cache.enabled=true +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +# Enabling H2 Console +spring.h2.console.enabled=true +spring.h2.console.path=/h2 +spring.jpa.hibernate.ddl-auto=update +server.port=8000 +spring.jpa.show-sql=true \ No newline at end of file diff --git a/spring-boot-modules/spring-caching/src/main/resources/logback.xml b/spring-boot-modules/spring-caching/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-boot-modules/spring-caching/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map b/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map deleted file mode 100644 index 7163a5f96e..0000000000 --- a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/inline.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 201a3a25457ab722584e"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length)\n \t\t\tresolves.shift()();\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t4: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn Promise.resolve();\n\n \t\t// an Promise means \"currently loading\".\n \t\tif(installedChunks[chunkId]) {\n \t\t\treturn installedChunks[chunkId][2];\n \t\t}\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunks[chunkId][2] = promise;\n\n \t\thead.appendChild(script);\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 201a3a25457ab722584e"],"sourceRoot":""} \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js.map b/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js.map deleted file mode 100644 index 676177396e..0000000000 --- a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/main.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///./src/app/app.component.css","webpack:///./src/app/book/book-detail/book-detail.component.css","webpack:///./src/app/book/book-list/book-list.component.css","webpack:///./src/app/rating/rating.component.css","webpack:///./src/app/app.component.html","webpack:///./src/app/book/book-detail/book-detail.component.html","webpack:///./src/app/book/book-list/book-list.component.html","webpack:///./src/app/rating/rating.component.html","webpack:///./src/app/http.service.ts","webpack:///./src/app/principal.ts","webpack:///./src/app/book.ts","webpack:///./src async","webpack:///./src/main.ts","webpack:///./src/app/app.component.ts","webpack:///./src/app/app.module.ts","webpack:///./src/app/book/book-detail/book-detail.component.ts","webpack:///./src/app/book/book-list/book-list.component.ts","webpack:///./src/app/click-stop-propagation.directive.ts","webpack:///./src/app/rating.ts","webpack:///./src/app/rating/rating.component.ts","webpack:///./src/environments/environment.ts"],"names":[],"mappings":"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","file":"main.bundle.js","sourcesContent":["exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".custom-close {\\r\\n float:right;\\r\\n}\\r\\n\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/app.component.css\n// module id = 144\n// module chunks = 1","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/book/book-detail/book-detail.component.css\n// module id = 145\n// module chunks = 1","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".custom-close {\\r\\n float:right;\\r\\n}\\r\\n\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/book/book-list/book-list.component.css\n// module id = 146\n// module chunks = 1","exports = module.exports = require(\"../../../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"div.progress {\\r\\n margin-top: 5px;\\r\\n}\\r\\n\\r\\n.rating:hover {\\r\\n border: solid blue;\\r\\n}\\r\\n\\r\\n.selected {\\r\\n border: solid blue;\\r\\n}\\r\\n\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/rating/rating.component.css\n// module id = 147\n// module chunks = 1","module.exports = \"\\r\\n\\r\\n
\\r\\n
\\r\\n

Book Rater App

\\r\\n

Anyone can view the books.

\\r\\n

Users can view and create ratings

\\r\\n

Admins can do anything!

\\r\\n
\\r\\n
\\r\\n\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n \\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n \\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/app.component.html\n// module id = 149\n// module chunks = 1","module.exports = \"
\\r\\n
\\r\\n \\r\\n

Title: {{selectedBook.title}}

\\r\\n
Author: {{selectedBook.author}}
\\r\\n

A quick summary of the book

\\r\\n \\r\\n
\\r\\n
\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/book/book-detail/book-detail.component.html\n// module id = 150\n// module chunks = 1","module.exports = \"
\\r\\n
\\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n \\r\\n

Title: {{book.title}}

\\r\\n
Author: {{book.author}}
\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n \\r\\n
\\r\\n
\\r\\n\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n \\r\\n

Add New Book

\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n
\\r\\n \\r\\n
\\r\\n
\\r\\n\\r\\n
\\r\\n
\\r\\n\\r\\n
\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/book/book-list/book-list.component.html\n// module id = 151\n// module chunks = 1","module.exports = \"Ratings:\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n
\\r\\n \\r\\n
\\r\\n
\\r\\n\\r\\n
\\r\\n
\\r\\n \\r\\n
\\r\\n \\r\\n \\r\\n \\r\\n
\\r\\n\\r\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/app/rating/rating.component.html\n// module id = 152\n// module chunks = 1","import {Injectable} from \"@angular/core\";\r\nimport {Observable} from \"rxjs\";\r\nimport {Response, Http, Headers, RequestOptions} from \"@angular/http\";\r\nimport {Book} from \"./book\";\r\nimport {Rating} from \"./rating\";\r\n\r\n@Injectable()\r\nexport class HttpService {\r\n\r\n constructor(private http: Http) { }\r\n\r\n me(): Observable {\r\n return this.http.get(\"/me\", this.makeOptions())\r\n }\r\n\r\n logout(): Observable {\r\n return this.http.post(\"/logout\", '', this.makeOptions())\r\n }\r\n\r\n getBooks(): Observable {\r\n return this.http.get(\"/book-service/books\", this.makeOptions())\r\n }\r\n\r\n updateBook(newBook: Book): Observable {\r\n return this.http.put(\"/book-service/books/\" + newBook.id, newBook, this.makeOptions())\r\n }\r\n\r\n deleteBook(book: Book): Observable {\r\n return this.http.delete(\"/book-service/books/\" + book.id, this.makeOptions())\r\n }\r\n\r\n createBook(newBook: Book): Observable {\r\n return this.http.post(\"/book-service/books\", newBook, this.makeOptions())\r\n }\r\n\r\n getRatings(bookId: number): Observable {\r\n return this.http.get(\"/rating-service/ratings?bookId=\" + bookId, this.makeOptions())\r\n }\r\n\r\n createRating(rating: Rating): Observable {\r\n return this.http.post(\"/rating-service/ratings\", rating, this.makeOptions())\r\n }\r\n\r\n deleteRating(ratingId: number) {\r\n return this.http.delete(\"/rating-service/ratings/\" + ratingId, this.makeOptions())\r\n }\r\n\r\n updateRating(rating: Rating) {\r\n return this.http.put(\"/rating-service/ratings/\" + rating.id, rating, this.makeOptions())\r\n }\r\n\r\n private makeOptions(): RequestOptions {\r\n let headers = new Headers({'Content-Type': 'application/json'});\r\n return new RequestOptions({headers: headers});\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/http.service.ts","export class Principal {\r\n public authenticated: boolean;\r\n public authorities: Authority[] = [];\r\n\r\n constructor(authenticated: boolean, authorities: any[]) {\r\n this.authenticated = authenticated;\r\n authorities.map(auth => this.authorities.push(new Authority(auth.authority)))\r\n }\r\n\r\n isAdmin() {\r\n return this.authorities.some((auth: Authority) => auth.authority.indexOf('ADMIN') > -1)\r\n }\r\n}\r\n\r\nexport class Authority {\r\n public authority: String;\r\n\r\n constructor(authority: String) {\r\n this.authority = authority;\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/principal.ts","export class Book {\r\n id: number;\r\n author: String;\r\n title: String;\r\n constructor(id: number, author: String, title: String){\r\n this.id = id;\r\n this.author = author;\r\n this.title = title;\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/book.ts","function webpackEmptyContext(req) {\n\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n}\nwebpackEmptyContext.keys = function() { return []; };\nwebpackEmptyContext.resolve = webpackEmptyContext;\nmodule.exports = webpackEmptyContext;\nwebpackEmptyContext.id = 74;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src async\n// module id = 74\n// module chunks = 1","import {enableProdMode} from \"@angular/core\";\r\nimport {platformBrowserDynamic} from \"@angular/platform-browser-dynamic\";\r\nimport {AppModule} from \"./app/app.module\";\r\nimport {environment} from \"./environments/environment\";\r\n\r\nif (environment.production) {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule);\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/main.ts","import {Component} from \"@angular/core\";\r\nimport {Principal} from \"./principal\";\r\nimport {Response} from \"@angular/http\";\r\nimport {Book} from \"./book\";\r\nimport {HttpService} from \"./http.service\";\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './app.component.html',\r\n styleUrls: ['./app.component.css']\r\n})\r\nexport class AppComponent {\r\n selectedBook: Book = null;\r\n principal: Principal = new Principal(false, []);\r\n loginFailed: boolean = false;\r\n\r\n constructor(private httpService: HttpService){}\r\n\r\n ngOnInit(): void {\r\n this.httpService.me()\r\n .subscribe((response: Response) => {\r\n let principalJson = response.json();\r\n this.principal = new Principal(principalJson.authenticated, principalJson.authorities);\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n onLogout() {\r\n this.httpService.logout()\r\n .subscribe((response: Response) => {\r\n if (response.status === 200) {\r\n this.loginFailed = false;\r\n this.principal = new Principal(false, []);\r\n window.location.replace(response.url);\r\n }\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n closeBookDetail() {\r\n this.selectedBook = null;\r\n }\r\n\r\n selectBook(book: Book) {\r\n this.selectedBook = book;\r\n }\r\n\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/app.component.ts","import {BrowserModule} from \"@angular/platform-browser\";\r\nimport {NgModule} from \"@angular/core\";\r\nimport {FormsModule} from \"@angular/forms\";\r\nimport {HttpModule} from \"@angular/http\";\r\nimport {AppComponent} from \"./app.component\";\r\nimport {RatingComponent} from \"./rating/rating.component\";\r\nimport {ClickStopPropagationDirective} from \"./click-stop-propagation.directive\";\r\nimport {BookDetailComponent} from \"./book/book-detail/book-detail.component\";\r\nimport {BookListComponent} from \"./book/book-list/book-list.component\";\r\nimport {HttpService} from \"./http.service\";\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n RatingComponent,\r\n ClickStopPropagationDirective,\r\n BookDetailComponent,\r\n BookListComponent\r\n ],\r\n imports: [\r\n BrowserModule,\r\n FormsModule,\r\n HttpModule\r\n ],\r\n providers: [HttpService],\r\n bootstrap: [AppComponent]\r\n})\r\nexport class AppModule { }\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/app.module.ts","import {Component, OnInit, Input, Output, EventEmitter} from \"@angular/core\";\r\nimport {Book} from \"../../book\";\r\nimport {Principal} from \"../../principal\";\r\n\r\n@Component({\r\n selector: 'app-book-detail',\r\n templateUrl: './book-detail.component.html',\r\n styleUrls: ['./book-detail.component.css']\r\n})\r\nexport class BookDetailComponent implements OnInit {\r\n\r\n @Input() selectedBook: Book = null;\r\n @Input() principal: Principal = null;\r\n @Output() closeBook: EventEmitter = new EventEmitter();\r\n\r\n\r\n constructor() { }\r\n\r\n ngOnInit() {\r\n }\r\n\r\n closeBookDetail() {\r\n this.closeBook.emit(null);\r\n }\r\n\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/book/book-detail/book-detail.component.ts","import {Component, OnInit, Input, Output, EventEmitter} from \"@angular/core\";\r\nimport {Principal} from \"../../principal\";\r\nimport {Book} from \"../../book\";\r\nimport {Response} from \"@angular/http\";\r\nimport {HttpService} from \"../../http.service\";\r\n\r\n@Component({\r\n selector: 'app-book-list',\r\n templateUrl: './book-list.component.html',\r\n styleUrls: ['./book-list.component.css']\r\n})\r\nexport class BookListComponent implements OnInit {\r\n\r\n @Input() principal: Principal = null;\r\n @Output() onBookSelected: EventEmitter = new EventEmitter();\r\n\r\n books: Book[] = [];\r\n newBooks: Book[] = [];\r\n newBook: Book = new Book(Math.floor(Math.random() * 1000), '', '');\r\n booksToEdit: number[] = [];\r\n isAddNewBook: boolean = false;\r\n selectedBook: Book = null;\r\n\r\n constructor(private httpService: HttpService) { }\r\n\r\n ngOnInit() {\r\n this.loadBooks();\r\n }\r\n\r\n loadBooks() {\r\n this.httpService.getBooks()\r\n .subscribe((response: Response) => {\r\n let booksJson: any[] = response.json()\r\n booksJson.forEach(book => {\r\n this.books.push(new Book(book.id, book.author, book.title));\r\n this.newBooks.push(new Book(book.id, book.author, book.title));\r\n })\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n cancelEditBook(bookIndex: number) {\r\n if (this.booksToEdit.indexOf(bookIndex) !== -1) {\r\n this.booksToEdit.splice(this.booksToEdit.indexOf(bookIndex), 1); //remove the index of the book to edit\r\n //get the original book\r\n let bookCopy: Book = new Book(this.books[bookIndex].id, this.books[bookIndex].author, this.books[bookIndex].title);\r\n this.newBooks.splice(bookIndex,1,bookCopy); //replace the edited book with the old book\r\n }\r\n }\r\n\r\n editBook(bookIndex: number) {\r\n this.booksToEdit.push(bookIndex);\r\n }\r\n\r\n saveBook(bookIndex: number, newBook: Book) {\r\n console.log(newBook);\r\n //save the book to the database\r\n this.httpService.updateBook(newBook)\r\n .subscribe((response: Response) => {\r\n let bookJson = response.json();\r\n let book: Book = new Book(bookJson.id, bookJson.author, bookJson.title);\r\n //update the current array of books\r\n let bookArr: Book = this.books.find(b => b.id === book.id);\r\n bookArr.title = book.title;\r\n bookArr.author = book.author;\r\n this.booksToEdit.splice(this.booksToEdit.indexOf(bookIndex), 1); //remove the index of the book to edit\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n\r\n\r\n }\r\n\r\n delete(bookIndex: number) {\r\n let book: Book = this.books[bookIndex];\r\n this.httpService.deleteBook(book)\r\n .subscribe(() => {\r\n if (this.selectedBook !== null && this.books[bookIndex].id === this.selectedBook.id) {\r\n this.selectedBook = null;\r\n this.onBookSelected.emit(this.selectedBook);\r\n }\r\n\r\n this.books.splice(bookIndex, 1); //remove the book at this index;\r\n this.newBooks.splice(bookIndex, 1); //remove the editing book at this index\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n activateAddNewBook() {\r\n this.isAddNewBook = true;\r\n this.newBook = new Book(null, '', '');\r\n }\r\n\r\n addNewBook(newBook: Book, element: any) {\r\n //write new book to db\r\n this.httpService.createBook(newBook)\r\n .subscribe((response: Response) => {\r\n let bookJson = response.json();\r\n let book: Book = new Book(bookJson.id, bookJson.author, bookJson.title);\r\n console.log(book);\r\n this.books.push(book);\r\n this.newBooks.push(book);\r\n this.newBook = new Book(Math.floor(Math.random() * 1000), '', '');\r\n element.focus();\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n cancelAddBook() {\r\n this.isAddNewBook = false;\r\n }\r\n\r\n\r\n selectBook(book: Book) {\r\n this.selectedBook = book;\r\n this.onBookSelected.emit(book);\r\n }\r\n\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/book/book-list/book-list.component.ts","import {Directive, HostListener} from \"@angular/core\";\r\n\r\n@Directive({\r\n selector: '[appClickStopPropagation]'\r\n})\r\nexport class ClickStopPropagationDirective\r\n{\r\n @HostListener(\"click\", [\"$event\"])\r\n public onClick(event: any): void\r\n {\r\n event.stopPropagation();\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/click-stop-propagation.directive.ts","export class Rating{\r\n id: number;\r\n bookId: number;\r\n stars: number;\r\n\r\n constructor(id: number, bookId: number, stars: number) {\r\n this.id = id;\r\n this.bookId = bookId;\r\n this.stars = stars;\r\n }\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/rating.ts","import {Component, OnInit, Input, OnChanges} from \"@angular/core\";\r\nimport {Rating} from \"../rating\";\r\nimport {Principal} from \"../principal\";\r\nimport {HttpService} from \"../http.service\";\r\nimport {Response} from \"@angular/http\";\r\n\r\n@Component({\r\n selector: 'app-rating',\r\n templateUrl: './rating.component.html',\r\n styleUrls: ['./rating.component.css']\r\n})\r\nexport class RatingComponent implements OnInit, OnChanges {\r\n\r\n @Input() bookId: number;\r\n @Input() principal: Principal = null;\r\n ratings: Rating[] = [];\r\n stars: number[] = [1,2,3,4,5];\r\n newRating: Rating = null;\r\n\r\n constructor(private httpService: HttpService) { }\r\n\r\n ngOnInit() {}\r\n\r\n ngOnChanges() {\r\n this.newRating = new Rating(null, this.bookId, 1);\r\n this.ratings = [];\r\n this.loadRatings();\r\n }\r\n\r\n findWidth(rating: Rating): String {\r\n let percent: number = (rating.stars/5)*100;\r\n return percent.toString() + '%';\r\n }\r\n\r\n private loadRatings() {\r\n this.httpService.getRatings(this.bookId)\r\n .subscribe((response: Response) => {\r\n let responseJson: any[] = response.json();\r\n responseJson.forEach(rating => this.ratings.push(new Rating(rating.id, rating.bookId, rating.stars)))\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n onSaveRating() {\r\n console.log(this.newRating);\r\n let ratingCopy: Rating = Object.assign({}, this.newRating);\r\n this.httpService.createRating(ratingCopy)\r\n .subscribe((response: Response) => {\r\n let ratingJson = response.json()\r\n this.ratings.push(new Rating(ratingJson.id, ratingJson.bookId, ratingJson.stars))\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n updateRating() {\r\n this.httpService.updateRating(this.newRating)\r\n .subscribe(() => {\r\n this.newRating = new Rating(null, this.bookId, 1);\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n }\r\n\r\n selectRating(rating: Rating) {\r\n if (this.principal.isAdmin()) {\r\n this.newRating = rating;\r\n }\r\n }\r\n\r\n cancelSelection() {\r\n this.newRating = new Rating(null, this.bookId, 1);\r\n }\r\n\r\n deleteRating(index: number) {\r\n let rating = this.ratings[index];\r\n this.httpService.deleteRating(rating.id)\r\n .subscribe(() => {\r\n if (this.ratings[index] === this.newRating) {\r\n this.newRating = new Rating(null, this.bookId, 1);\r\n }\r\n this.ratings.splice(index, 1);\r\n }, (error) => {\r\n console.log(error);\r\n });\r\n\r\n }\r\n\r\n}\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/app/rating/rating.component.ts","// The file contents for the current environment will overwrite these during build.\r\n// The build system defaults to the dev environment which uses `environment.ts`, but if you do\r\n// `ng build --env=prod` then `environment.prod.ts` will be used instead.\r\n// The list of which env maps to which file can be found in `.angular-cli.json`.\r\n\r\nexport const environment = {\r\n production: false\r\n};\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/environments/environment.ts"],"sourceRoot":""} \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js.map b/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js.map deleted file mode 100644 index 4304ec0970..0000000000 --- a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/polyfills.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///./~/core-js/modules/_an-object.js","webpack:///./~/core-js/modules/_export.js","webpack:///./~/core-js/modules/_is-object.js","webpack:///./~/core-js/modules/_global.js","webpack:///./~/core-js/modules/_has.js","webpack:///./~/core-js/modules/_metadata.js","webpack:///./~/core-js/modules/_wks.js","webpack:///./~/core-js/modules/_fails.js","webpack:///./~/core-js/modules/_object-dp.js","webpack:///./~/core-js/modules/_descriptors.js","webpack:///./~/core-js/modules/_object-gpo.js","webpack:///./~/core-js/modules/_a-function.js","webpack:///./~/core-js/modules/_core.js","webpack:///./~/core-js/modules/_ctx.js","webpack:///./~/core-js/modules/_object-gopd.js","webpack:///./~/core-js/modules/_redefine.js","webpack:///./~/core-js/modules/_for-of.js","webpack:///./~/core-js/modules/_hide.js","webpack:///./~/core-js/modules/_meta.js","webpack:///./~/core-js/modules/_property-desc.js","webpack:///./~/core-js/modules/_uid.js","webpack:///(webpack)/buildin/global.js","webpack:///./~/core-js/modules/_an-instance.js","webpack:///./~/core-js/modules/_cof.js","webpack:///./~/core-js/modules/_collection.js","webpack:///./~/core-js/modules/_defined.js","webpack:///./~/core-js/modules/_enum-bug-keys.js","webpack:///./~/core-js/modules/_iobject.js","webpack:///./~/core-js/modules/_iterators.js","webpack:///./~/core-js/modules/_object-create.js","webpack:///./~/core-js/modules/_redefine-all.js","webpack:///./~/core-js/modules/_set-to-string-tag.js","webpack:///./~/core-js/modules/_shared-key.js","webpack:///./~/core-js/modules/_shared.js","webpack:///./~/core-js/modules/_to-iobject.js","webpack:///./~/core-js/modules/_to-length.js","webpack:///./~/core-js/modules/_to-object.js","webpack:///./~/core-js/modules/_to-primitive.js","webpack:///./~/core-js/modules/_array-methods.js","webpack:///./~/core-js/modules/_collection-strong.js","webpack:///./~/core-js/modules/_dom-create.js","webpack:///./~/core-js/modules/_ie8-dom-define.js","webpack:///./~/core-js/modules/_iter-create.js","webpack:///./~/core-js/modules/_object-gops.js","webpack:///./~/core-js/modules/_object-keys-internal.js","webpack:///./~/core-js/modules/_object-keys.js","webpack:///./~/core-js/modules/_object-pie.js","webpack:///./~/core-js/modules/_set-proto.js","webpack:///./~/core-js/modules/_to-integer.js","webpack:///./src/polyfills.ts","webpack:///./~/core-js/es6/reflect.js","webpack:///./~/core-js/es7/reflect.js","webpack:///./~/core-js/modules/_array-from-iterable.js","webpack:///./~/core-js/modules/_array-includes.js","webpack:///./~/core-js/modules/_array-species-constructor.js","webpack:///./~/core-js/modules/_array-species-create.js","webpack:///./~/core-js/modules/_bind.js","webpack:///./~/core-js/modules/_classof.js","webpack:///./~/core-js/modules/_collection-weak.js","webpack:///./~/core-js/modules/_html.js","webpack:///./~/core-js/modules/_inherit-if-required.js","webpack:///./~/core-js/modules/_invoke.js","webpack:///./~/core-js/modules/_is-array-iter.js","webpack:///./~/core-js/modules/_is-array.js","webpack:///./~/core-js/modules/_iter-call.js","webpack:///./~/core-js/modules/_iter-define.js","webpack:///./~/core-js/modules/_iter-detect.js","webpack:///./~/core-js/modules/_iter-step.js","webpack:///./~/core-js/modules/_library.js","webpack:///./~/core-js/modules/_object-assign.js","webpack:///./~/core-js/modules/_object-dps.js","webpack:///./~/core-js/modules/_object-gopn.js","webpack:///./~/core-js/modules/_own-keys.js","webpack:///./~/core-js/modules/_set-species.js","webpack:///./~/core-js/modules/_to-index.js","webpack:///./~/core-js/modules/core.get-iterator-method.js","webpack:///./~/core-js/modules/es6.map.js","webpack:///./~/core-js/modules/es6.reflect.apply.js","webpack:///./~/core-js/modules/es6.reflect.construct.js","webpack:///./~/core-js/modules/es6.reflect.define-property.js","webpack:///./~/core-js/modules/es6.reflect.delete-property.js","webpack:///./~/core-js/modules/es6.reflect.enumerate.js","webpack:///./~/core-js/modules/es6.reflect.get-own-property-descriptor.js","webpack:///./~/core-js/modules/es6.reflect.get-prototype-of.js","webpack:///./~/core-js/modules/es6.reflect.get.js","webpack:///./~/core-js/modules/es6.reflect.has.js","webpack:///./~/core-js/modules/es6.reflect.is-extensible.js","webpack:///./~/core-js/modules/es6.reflect.own-keys.js","webpack:///./~/core-js/modules/es6.reflect.prevent-extensions.js","webpack:///./~/core-js/modules/es6.reflect.set-prototype-of.js","webpack:///./~/core-js/modules/es6.reflect.set.js","webpack:///./~/core-js/modules/es6.set.js","webpack:///./~/core-js/modules/es6.weak-map.js","webpack:///./~/core-js/modules/es7.reflect.define-metadata.js","webpack:///./~/core-js/modules/es7.reflect.delete-metadata.js","webpack:///./~/core-js/modules/es7.reflect.get-metadata-keys.js","webpack:///./~/core-js/modules/es7.reflect.get-metadata.js","webpack:///./~/core-js/modules/es7.reflect.get-own-metadata-keys.js","webpack:///./~/core-js/modules/es7.reflect.get-own-metadata.js","webpack:///./~/core-js/modules/es7.reflect.has-metadata.js","webpack:///./~/core-js/modules/es7.reflect.has-own-metadata.js","webpack:///./~/core-js/modules/es7.reflect.metadata.js","webpack:///./~/process/browser.js","webpack:///./~/zone.js/dist/zone.js"],"names":[],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,uBAAuB;AAC5G,mEAAmE;AACnE,gEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,eAAe;AACf,eAAe;AACf,eAAe;AACf,gBAAgB;AAChB,yB;;;;;;;AC1CA;AACA;AACA,E;;;;;;ACFA;AACA;AACA;AACA,uCAAuC,gC;;;;;;;ACHvC,uBAAuB;AACvB;AACA;AACA,E;;;;;;ACHA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,gBAAgB,EAAE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;AClDA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,uB;;;;;;ACVA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,E;;;;;;ACNA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,UAAU;AACb;AACA;AACA;AACA,E;;;;;;ACfA;AACA;AACA,iCAAiC,QAAQ,gBAAgB,UAAU,GAAG;AACtE,CAAC,E;;;;;;ACHD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,E;;;;;;;;;ACZA;AACA;AACA;AACA,E;;;;;;ACHA,6BAA6B;AAC7B,qCAAqC,gC;;;;;;ACDrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG,UAAU;AACb;AACA,E;;;;;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,CAAC,E;;;;;;;;;AC/BD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,iBAAiB,EAAE;AACxD;AACA;AACA;AACA;AACA;AACA,gEAAgE,gBAAgB;AAChF;AACA;AACA,GAAG,2CAA2C,gCAAgC;AAC9E;AACA;AACA;AACA;AACA;AACA,wB;;;;;;ACxBA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA,E;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD,CAAC;AACD;AACA,qBAAqB;AACrB;AACA,SAAS;AACT,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACPA;AACA;AACA;AACA;AACA,E;;;;;;;ACJA;;AAEA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA,4CAA4C;;AAE5C;;;;;;;ACpBA;AACA;AACA;AACA,GAAG;AACH,E;;;;;;ACJA,iBAAiB;;AAEjB;AACA;AACA,E;;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,OAAO;AACP;AACA,OAAO,kCAAkC,gCAAgC,aAAa;AACtF,6BAA6B,mCAAmC,aAAa;AAC7E;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,2DAA2D;AAC3D;AACA,gDAAgD,iBAAiB,EAAE;AACnE;AACA,0DAA0D,aAAa,EAAE;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,0B;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA,E;;;;;;ACpFA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA;AACA,a;;;;;;ACHA;AACA;AACA;AACA;AACA,E;;;;;;ACJA,oB;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;;;;;;ACxCA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA;;AAEA;AACA,kEAAkE,+BAA+B;AACjG,E;;;;;;ACNA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA,mDAAmD;AACnD;AACA,uCAAuC;AACvC,E;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACLA;AACA;AACA;AACA;AACA,2DAA2D;AAC3D,E;;;;;;ACLA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe;AACxB;AACA;AACA;AACA,sCAAsC;AACtC;AACA,8BAA8B;AAC9B,6BAA6B;AAC7B,+BAA+B;AAC/B,mCAAmC;AACnC,SAAS,+BAA+B;AACxC;AACA;AACA;AACA;AACA,E;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,0BAA0B;AAC1B,0BAA0B;AAC1B,qBAAqB;AACrB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,6DAA6D,OAAO;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,qBAAqB;AACrB,0BAA0B;AAC1B,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,E;;;;;;AC7IA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACNA;AACA,qEAAsE,gBAAgB,UAAU,GAAG;AACnG,CAAC,E;;;;;;;ACFD;AACA;AACA;AACA;AACA;;AAEA;AACA,0FAAgF,aAAa,EAAE;;AAE/F;AACA,qDAAqD,0BAA0B;AAC/E;AACA,E;;;;;;ACZA,yC;;;;;;ACAA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;AChBA;AACA;AACA;;AAEA;AACA;AACA,E;;;;;;ACNA,cAAc,sB;;;;;;ACAd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,OAAO,UAAU,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,GAAG;AACR;AACA,E;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;;;;;;;;;;;;;;;;;;;;;ACL6B;AACA;AACF;AAI3B;;GAEG;AAEH;;;GAGG;AACH,oDAAoD;;;;;;;;;;;;;;;;;;;;ACdpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iD;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,WAAW,eAAe;AAC/B;AACA,KAAK;AACL;AACA,E;;;;;;ACpBA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,E;;;;;;ACfA;AACA;;AAEA;AACA;AACA,E;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B,SAAS;AACnC;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACvBA;AACA;AACA;AACA;AACA,yBAAyB,kBAAkB,EAAE;;AAE7C;AACA;AACA;AACA;AACA,GAAG,UAAU;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,0BAA0B;AAC1B;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,E;;;;;;AClFA,6E;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,E;;;;;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,E;;;;;;ACfA;AACA;AACA;AACA;;AAEA;AACA;AACA,E;;;;;;ACPA;AACA;AACA;AACA;AACA,E;;;;;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,E;;;;;;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,aAAa;;AAEzC;AACA;AACA;AACA;AACA;AACA,wCAAwC,oCAAoC;AAC5E,4CAA4C,oCAAoC;AAChF,KAAK,2BAA2B,oCAAoC;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA,iCAAiC,2BAA2B;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,E;;;;;;ACrEA;AACA;;AAEA;AACA;AACA,+BAA+B,qBAAqB;AACpD,+BAA+B,SAAS,EAAE;AAC1C,CAAC,UAAU;;AAEX;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,SAAS,mBAAmB;AACvD,+BAA+B,aAAa;AAC5C;AACA,GAAG,UAAU;AACb;AACA,E;;;;;;ACpBA;AACA,UAAU;AACV,E;;;;;;ACFA,uB;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,UAAU,EAAE;AAC9C,mBAAmB,sCAAsC;AACzD,CAAC,oCAAoC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH,CAAC,W;;;;;;AChCD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACZA;AACA;AACA;;AAEA;AACA;AACA,E;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;ACTA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAoB,aAAa;AACjC,GAAG;AACH,E;;;;;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;ACPA;AACA;;AAEA;AACA;AACA,wBAAwB,mEAAmE;AAC3F,CAAC;AACD;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA,CAAC,gB;;;;;;AChBD;AACA;AACA;AACA;AACA,qDAAmD;AACnD;AACA;AACA;AACA,qBAAqB;AACrB,CAAC;AACD;AACA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACfD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAoD;;AAEpD;AACA;AACA;AACA;AACA,kCAAkC;AAClC,CAAC;AACD;AACA,yBAAyB;AACzB,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;AC9CD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,gCAAgC,MAAM,SAAS,OAAO,SAAS;AAC/D,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,CAAC,E;;;;;;ACrBD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;;ACVD;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC,GAAG;AACH,UAAU;AACV,CAAC;;AAED;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACzBD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACTD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACTD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA+B,SAAS,E;;;;;;ACpBxC;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACPD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,CAAC,E;;;;;;ACVD;AACA;;AAEA,+BAA+B,kCAAgC,E;;;;;;ACH/D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,CAAC,E;;;;;;ACfD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,CAAC,E;;;;;;ACdD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,+BAA+B,SAAS,E;;;;;;;AC9BxC;AACA;;AAEA;AACA;AACA,wBAAwB,mEAAmE;AAC3F,CAAC;AACD;AACA;AACA;AACA;AACA,CAAC,U;;;;;;;ACXD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL,GAAG;AACH,C;;;;;;ACvDA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA,EAAE,E;;;;;;ACPF;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,E;;;;;;ACdF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA,EAAE,E;;;;;;AClBF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA,EAAE,E;;;;;;AChBF;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA,EAAE,E;;;;;;ACPF;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA,EAAE,E;;;;;;ACRF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA,EAAE,E;;;;;;ACfF;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA,EAAE,E;;;;;;ACRF;AACA;AACA;AACA;AACA;;AAEA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE,E;;;;;;;;;;;;ACdF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,uBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,2BAA2B;AAC3B;AACA;AACA;AACA,4BAA4B,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnLtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC,qBAAqB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;;AAET;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,uBAAuB;AAC9D,uCAAuC,kBAAkB;AACzD,oCAAoC,eAAe;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,kBAAkB;AACzD,uCAAuC,kBAAkB;AACzD,oCAAoC,eAAe;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,0BAA0B;AACrD;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,kFAAkF,gEAAgE,EAAE;AACpJ;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wHAAwH,wBAAwB,oCAAoC;AACpL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,kBAAkB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,kBAAkB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,oDAAoD;AAC9F;AACA;AACA;AACA;AACA;AACA,2BAA2B,mCAAmC;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,gBAAgB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,sBAAsB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,+CAA+C,sBAAsB;AACrE;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,kBAAkB,EAAE;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,kCAAkC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,oBAAoB,EAAE;AACjF;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,iCAAiC;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA,8FAA8F,aAAa,EAAE;AAC7G;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,+BAA+B,8BAA8B;AAC7D;AACA;AACA,iCAAiC,QAAQ;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,8DAA8D;AAC9D;AACA;AACA,uDAAuD,uDAAuD;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAyB;AAC5C;AACA;AACA;AACA,uBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAA0B;AACjE,qCAAqC,yBAAyB;AAC9D,+BAA+B,mBAAmB;AAClD,iCAAiC,0CAA0C;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,wCAAwC;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAA0B;AACjE,iCAAiC,0CAA0C;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA,+BAA+B,gCAAgC;AAC/D,kCAAkC,sCAAsC;AACxE,iCAAiC,0CAA0C;AAC3E;AACA,iDAAiD,2FAA2F,EAAE;AAC9I,oDAAoD,qEAAqE,EAAE;AAC3H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,EAAE;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,8DAA8D,0BAA0B;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA,uBAAuB,uBAAuB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,EAAE;AACZ;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,EAAE;AACZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,0BAA0B,EAAE;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,+BAA+B,EAAE;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,uFAAuF;AACvF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,mBAAmB,uBAAuB;AAC1C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,4BAA4B;AAC3C;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uFAAuF;AACvF;AACA;AACA,MAAM,EAAE;AACR,uFAAuF;AACvF;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA,MAAM,EAAE;AACR,iGAAiG;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,EAAE;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,0CAA0C;AACxG;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,CAAC","file":"polyfills.bundle.js","sourcesContent":["var isObject = require('./_is-object');\nmodule.exports = function(it){\n if(!isObject(it))throw TypeError(it + ' is not an object!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_an-object.js\n// module id = 0\n// module chunks = 0","var global = require('./_global')\n , core = require('./_core')\n , hide = require('./_hide')\n , redefine = require('./_redefine')\n , ctx = require('./_ctx')\n , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n var IS_FORCED = type & $export.F\n , IS_GLOBAL = type & $export.G\n , IS_STATIC = type & $export.S\n , IS_PROTO = type & $export.P\n , IS_BIND = type & $export.B\n , target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE]\n , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})\n , expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {})\n , key, own, out, exp;\n if(IS_GLOBAL)source = name;\n for(key in source){\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n // export native or passed\n out = (own ? target : source)[key];\n // bind timers to global for call from export context\n exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // extend global\n if(target)redefine(target, key, out, type & $export.U);\n // export\n if(exports[key] != out)hide(exports, key, exp);\n if(IS_PROTO && expProto[key] != out)expProto[key] = out;\n }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library` \nmodule.exports = $export;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_export.js\n// module id = 1\n// module chunks = 0","module.exports = function(it){\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_is-object.js\n// module id = 3\n// module chunks = 0","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_global.js\n// module id = 4\n// module chunks = 0","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function(it, key){\n return hasOwnProperty.call(it, key);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_has.js\n// module id = 6\n// module chunks = 0","var Map = require('./es6.map')\n , $export = require('./_export')\n , shared = require('./_shared')('metadata')\n , store = shared.store || (shared.store = new (require('./es6.weak-map')));\n\nvar getOrCreateMetadataMap = function(target, targetKey, create){\n var targetMetadata = store.get(target);\n if(!targetMetadata){\n if(!create)return undefined;\n store.set(target, targetMetadata = new Map);\n }\n var keyMetadata = targetMetadata.get(targetKey);\n if(!keyMetadata){\n if(!create)return undefined;\n targetMetadata.set(targetKey, keyMetadata = new Map);\n } return keyMetadata;\n};\nvar ordinaryHasOwnMetadata = function(MetadataKey, O, P){\n var metadataMap = getOrCreateMetadataMap(O, P, false);\n return metadataMap === undefined ? false : metadataMap.has(MetadataKey);\n};\nvar ordinaryGetOwnMetadata = function(MetadataKey, O, P){\n var metadataMap = getOrCreateMetadataMap(O, P, false);\n return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);\n};\nvar ordinaryDefineOwnMetadata = function(MetadataKey, MetadataValue, O, P){\n getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);\n};\nvar ordinaryOwnMetadataKeys = function(target, targetKey){\n var metadataMap = getOrCreateMetadataMap(target, targetKey, false)\n , keys = [];\n if(metadataMap)metadataMap.forEach(function(_, key){ keys.push(key); });\n return keys;\n};\nvar toMetaKey = function(it){\n return it === undefined || typeof it == 'symbol' ? it : String(it);\n};\nvar exp = function(O){\n $export($export.S, 'Reflect', O);\n};\n\nmodule.exports = {\n store: store,\n map: getOrCreateMetadataMap,\n has: ordinaryHasOwnMetadata,\n get: ordinaryGetOwnMetadata,\n set: ordinaryDefineOwnMetadata,\n keys: ordinaryOwnMetadataKeys,\n key: toMetaKey,\n exp: exp\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_metadata.js\n// module id = 7\n// module chunks = 0","var store = require('./_shared')('wks')\n , uid = require('./_uid')\n , Symbol = require('./_global').Symbol\n , USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function(name){\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_wks.js\n// module id = 8\n// module chunks = 0","module.exports = function(exec){\n try {\n return !!exec();\n } catch(e){\n return true;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_fails.js\n// module id = 9\n// module chunks = 0","var anObject = require('./_an-object')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , toPrimitive = require('./_to-primitive')\n , dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if(IE8_DOM_DEFINE)try {\n return dP(O, P, Attributes);\n } catch(e){ /* empty */ }\n if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n if('value' in Attributes)O[P] = Attributes.value;\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-dp.js\n// module id = 10\n// module chunks = 0","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function(){\n return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_descriptors.js\n// module id = 11\n// module chunks = 0","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has')\n , toObject = require('./_to-object')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function(O){\n O = toObject(O);\n if(has(O, IE_PROTO))return O[IE_PROTO];\n if(typeof O.constructor == 'function' && O instanceof O.constructor){\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-gpo.js\n// module id = 12\n// module chunks = 0","module.exports = function(it){\n if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_a-function.js\n// module id = 16\n// module chunks = 0","var core = module.exports = {version: '2.4.0'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_core.js\n// module id = 17\n// module chunks = 0","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function(fn, that, length){\n aFunction(fn);\n if(that === undefined)return fn;\n switch(length){\n case 1: return function(a){\n return fn.call(that, a);\n };\n case 2: return function(a, b){\n return fn.call(that, a, b);\n };\n case 3: return function(a, b, c){\n return fn.call(that, a, b, c);\n };\n }\n return function(/* ...args */){\n return fn.apply(that, arguments);\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_ctx.js\n// module id = 18\n// module chunks = 0","var pIE = require('./_object-pie')\n , createDesc = require('./_property-desc')\n , toIObject = require('./_to-iobject')\n , toPrimitive = require('./_to-primitive')\n , has = require('./_has')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P){\n O = toIObject(O);\n P = toPrimitive(P, true);\n if(IE8_DOM_DEFINE)try {\n return gOPD(O, P);\n } catch(e){ /* empty */ }\n if(has(O, P))return createDesc(!pIE.f.call(O, P), O[P]);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-gopd.js\n// module id = 19\n// module chunks = 0","var global = require('./_global')\n , hide = require('./_hide')\n , has = require('./_has')\n , SRC = require('./_uid')('src')\n , TO_STRING = 'toString'\n , $toString = Function[TO_STRING]\n , TPL = ('' + $toString).split(TO_STRING);\n\nrequire('./_core').inspectSource = function(it){\n return $toString.call(it);\n};\n\n(module.exports = function(O, key, val, safe){\n var isFunction = typeof val == 'function';\n if(isFunction)has(val, 'name') || hide(val, 'name', key);\n if(O[key] === val)return;\n if(isFunction)has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n if(O === global){\n O[key] = val;\n } else {\n if(!safe){\n delete O[key];\n hide(O, key, val);\n } else {\n if(O[key])O[key] = val;\n else hide(O, key, val);\n }\n }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString(){\n return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_redefine.js\n// module id = 20\n// module chunks = 0","var ctx = require('./_ctx')\n , call = require('./_iter-call')\n , isArrayIter = require('./_is-array-iter')\n , anObject = require('./_an-object')\n , toLength = require('./_to-length')\n , getIterFn = require('./core.get-iterator-method')\n , BREAK = {}\n , RETURN = {};\nvar exports = module.exports = function(iterable, entries, fn, that, ITERATOR){\n var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable)\n , f = ctx(fn, that, entries ? 2 : 1)\n , index = 0\n , length, step, iterator, result;\n if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if(result === BREAK || result === RETURN)return result;\n } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){\n result = call(iterator, f, step.value, entries);\n if(result === BREAK || result === RETURN)return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_for-of.js\n// module id = 24\n// module chunks = 0","var dP = require('./_object-dp')\n , createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function(object, key, value){\n return dP.f(object, key, createDesc(1, value));\n} : function(object, key, value){\n object[key] = value;\n return object;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_hide.js\n// module id = 25\n// module chunks = 0","var META = require('./_uid')('meta')\n , isObject = require('./_is-object')\n , has = require('./_has')\n , setDesc = require('./_object-dp').f\n , id = 0;\nvar isExtensible = Object.isExtensible || function(){\n return true;\n};\nvar FREEZE = !require('./_fails')(function(){\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function(it){\n setDesc(it, META, {value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n }});\n};\nvar fastKey = function(it, create){\n // return primitive with prefix\n if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return 'F';\n // not necessary to add metadata\n if(!create)return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function(it, create){\n if(!has(it, META)){\n // can't set metadata to uncaught frozen object\n if(!isExtensible(it))return true;\n // not necessary to add metadata\n if(!create)return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function(it){\n if(FREEZE && meta.NEED && isExtensible(it) && !has(it, META))setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_meta.js\n// module id = 26\n// module chunks = 0","module.exports = function(bitmap, value){\n return {\n enumerable : !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable : !(bitmap & 4),\n value : value\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_property-desc.js\n// module id = 27\n// module chunks = 0","var id = 0\n , px = Math.random();\nmodule.exports = function(key){\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_uid.js\n// module id = 28\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 30\n// module chunks = 0 3","module.exports = function(it, Constructor, name, forbiddenField){\n if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_an-instance.js\n// module id = 31\n// module chunks = 0","var toString = {}.toString;\n\nmodule.exports = function(it){\n return toString.call(it).slice(8, -1);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_cof.js\n// module id = 32\n// module chunks = 0","'use strict';\nvar global = require('./_global')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , redefineAll = require('./_redefine-all')\n , meta = require('./_meta')\n , forOf = require('./_for-of')\n , anInstance = require('./_an-instance')\n , isObject = require('./_is-object')\n , fails = require('./_fails')\n , $iterDetect = require('./_iter-detect')\n , setToStringTag = require('./_set-to-string-tag')\n , inheritIfRequired = require('./_inherit-if-required');\n\nmodule.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){\n var Base = global[NAME]\n , C = Base\n , ADDER = IS_MAP ? 'set' : 'add'\n , proto = C && C.prototype\n , O = {};\n var fixMethod = function(KEY){\n var fn = proto[KEY];\n redefine(proto, KEY,\n KEY == 'delete' ? function(a){\n return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n } : KEY == 'has' ? function has(a){\n return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n } : KEY == 'get' ? function get(a){\n return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);\n } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; }\n : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; }\n );\n };\n if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){\n new C().entries().next();\n }))){\n // create collection constructor\n C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);\n redefineAll(C.prototype, methods);\n meta.NEED = true;\n } else {\n var instance = new C\n // early implementations not supports chaining\n , HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance\n // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false\n , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); })\n // most early implementations doesn't supports iterables, most modern - not close it correctly\n , ACCEPT_ITERABLES = $iterDetect(function(iter){ new C(iter); }) // eslint-disable-line no-new\n // for early implementations -0 and +0 not the same\n , BUGGY_ZERO = !IS_WEAK && fails(function(){\n // V8 ~ Chromium 42- fails only with 5+ elements\n var $instance = new C()\n , index = 5;\n while(index--)$instance[ADDER](index, index);\n return !$instance.has(-0);\n });\n if(!ACCEPT_ITERABLES){ \n C = wrapper(function(target, iterable){\n anInstance(target, C, NAME);\n var that = inheritIfRequired(new Base, target, C);\n if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n return that;\n });\n C.prototype = proto;\n proto.constructor = C;\n }\n if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){\n fixMethod('delete');\n fixMethod('has');\n IS_MAP && fixMethod('get');\n }\n if(BUGGY_ZERO || HASNT_CHAINING)fixMethod(ADDER);\n // weak collections should not contains .clear method\n if(IS_WEAK && proto.clear)delete proto.clear;\n }\n\n setToStringTag(C, NAME);\n\n O[NAME] = C;\n $export($export.G + $export.W + $export.F * (C != Base), O);\n\n if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP);\n\n return C;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_collection.js\n// module id = 33\n// module chunks = 0","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function(it){\n if(it == undefined)throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_defined.js\n// module id = 34\n// module chunks = 0","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_enum-bug-keys.js\n// module id = 35\n// module chunks = 0","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iobject.js\n// module id = 36\n// module chunks = 0","module.exports = {};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iterators.js\n// module id = 37\n// module chunks = 0","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object')\n , dPs = require('./_object-dps')\n , enumBugKeys = require('./_enum-bug-keys')\n , IE_PROTO = require('./_shared-key')('IE_PROTO')\n , Empty = function(){ /* empty */ }\n , PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function(){\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe')\n , i = enumBugKeys.length\n , lt = '<'\n , gt = '>'\n , iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties){\n var result;\n if(O !== null){\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty;\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-create.js\n// module id = 38\n// module chunks = 0","var redefine = require('./_redefine');\nmodule.exports = function(target, src, safe){\n for(var key in src)redefine(target, key, src[key], safe);\n return target;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_redefine-all.js\n// module id = 39\n// module chunks = 0","var def = require('./_object-dp').f\n , has = require('./_has')\n , TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function(it, tag, stat){\n if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_set-to-string-tag.js\n// module id = 40\n// module chunks = 0","var shared = require('./_shared')('keys')\n , uid = require('./_uid');\nmodule.exports = function(key){\n return shared[key] || (shared[key] = uid(key));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_shared-key.js\n// module id = 41\n// module chunks = 0","var global = require('./_global')\n , SHARED = '__core-js_shared__'\n , store = global[SHARED] || (global[SHARED] = {});\nmodule.exports = function(key){\n return store[key] || (store[key] = {});\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_shared.js\n// module id = 42\n// module chunks = 0","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject')\n , defined = require('./_defined');\nmodule.exports = function(it){\n return IObject(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-iobject.js\n// module id = 43\n// module chunks = 0","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer')\n , min = Math.min;\nmodule.exports = function(it){\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-length.js\n// module id = 44\n// module chunks = 0","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function(it){\n return Object(defined(it));\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-object.js\n// module id = 45\n// module chunks = 0","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n if(!isObject(it))return it;\n var fn, val;\n if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-primitive.js\n// module id = 46\n// module chunks = 0","// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx = require('./_ctx')\n , IObject = require('./_iobject')\n , toObject = require('./_to-object')\n , toLength = require('./_to-length')\n , asc = require('./_array-species-create');\nmodule.exports = function(TYPE, $create){\n var IS_MAP = TYPE == 1\n , IS_FILTER = TYPE == 2\n , IS_SOME = TYPE == 3\n , IS_EVERY = TYPE == 4\n , IS_FIND_INDEX = TYPE == 6\n , NO_HOLES = TYPE == 5 || IS_FIND_INDEX\n , create = $create || asc;\n return function($this, callbackfn, that){\n var O = toObject($this)\n , self = IObject(O)\n , f = ctx(callbackfn, that, 3)\n , length = toLength(self.length)\n , index = 0\n , result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined\n , val, res;\n for(;length > index; index++)if(NO_HOLES || index in self){\n val = self[index];\n res = f(val, index, O);\n if(TYPE){\n if(IS_MAP)result[index] = res; // map\n else if(res)switch(TYPE){\n case 3: return true; // some\n case 5: return val; // find\n case 6: return index; // findIndex\n case 2: result.push(val); // filter\n } else if(IS_EVERY)return false; // every\n }\n }\n return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_array-methods.js\n// module id = 52\n// module chunks = 0","'use strict';\nvar dP = require('./_object-dp').f\n , create = require('./_object-create')\n , redefineAll = require('./_redefine-all')\n , ctx = require('./_ctx')\n , anInstance = require('./_an-instance')\n , defined = require('./_defined')\n , forOf = require('./_for-of')\n , $iterDefine = require('./_iter-define')\n , step = require('./_iter-step')\n , setSpecies = require('./_set-species')\n , DESCRIPTORS = require('./_descriptors')\n , fastKey = require('./_meta').fastKey\n , SIZE = DESCRIPTORS ? '_s' : 'size';\n\nvar getEntry = function(that, key){\n // fast case\n var index = fastKey(key), entry;\n if(index !== 'F')return that._i[index];\n // frozen object case\n for(entry = that._f; entry; entry = entry.n){\n if(entry.k == key)return entry;\n }\n};\n\nmodule.exports = {\n getConstructor: function(wrapper, NAME, IS_MAP, ADDER){\n var C = wrapper(function(that, iterable){\n anInstance(that, C, NAME, '_i');\n that._i = create(null); // index\n that._f = undefined; // first entry\n that._l = undefined; // last entry\n that[SIZE] = 0; // size\n if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n });\n redefineAll(C.prototype, {\n // 23.1.3.1 Map.prototype.clear()\n // 23.2.3.2 Set.prototype.clear()\n clear: function clear(){\n for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){\n entry.r = true;\n if(entry.p)entry.p = entry.p.n = undefined;\n delete data[entry.i];\n }\n that._f = that._l = undefined;\n that[SIZE] = 0;\n },\n // 23.1.3.3 Map.prototype.delete(key)\n // 23.2.3.4 Set.prototype.delete(value)\n 'delete': function(key){\n var that = this\n , entry = getEntry(that, key);\n if(entry){\n var next = entry.n\n , prev = entry.p;\n delete that._i[entry.i];\n entry.r = true;\n if(prev)prev.n = next;\n if(next)next.p = prev;\n if(that._f == entry)that._f = next;\n if(that._l == entry)that._l = prev;\n that[SIZE]--;\n } return !!entry;\n },\n // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)\n // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)\n forEach: function forEach(callbackfn /*, that = undefined */){\n anInstance(this, C, 'forEach');\n var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3)\n , entry;\n while(entry = entry ? entry.n : this._f){\n f(entry.v, entry.k, this);\n // revert to the last existing entry\n while(entry && entry.r)entry = entry.p;\n }\n },\n // 23.1.3.7 Map.prototype.has(key)\n // 23.2.3.7 Set.prototype.has(value)\n has: function has(key){\n return !!getEntry(this, key);\n }\n });\n if(DESCRIPTORS)dP(C.prototype, 'size', {\n get: function(){\n return defined(this[SIZE]);\n }\n });\n return C;\n },\n def: function(that, key, value){\n var entry = getEntry(that, key)\n , prev, index;\n // change existing entry\n if(entry){\n entry.v = value;\n // create new entry\n } else {\n that._l = entry = {\n i: index = fastKey(key, true), // <- index\n k: key, // <- key\n v: value, // <- value\n p: prev = that._l, // <- previous entry\n n: undefined, // <- next entry\n r: false // <- removed\n };\n if(!that._f)that._f = entry;\n if(prev)prev.n = entry;\n that[SIZE]++;\n // add to index\n if(index !== 'F')that._i[index] = entry;\n } return that;\n },\n getEntry: getEntry,\n setStrong: function(C, NAME, IS_MAP){\n // add .keys, .values, .entries, [@@iterator]\n // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11\n $iterDefine(C, NAME, function(iterated, kind){\n this._t = iterated; // target\n this._k = kind; // kind\n this._l = undefined; // previous\n }, function(){\n var that = this\n , kind = that._k\n , entry = that._l;\n // revert to the last existing entry\n while(entry && entry.r)entry = entry.p;\n // get next entry\n if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){\n // or finish the iteration\n that._t = undefined;\n return step(1);\n }\n // return step by kind\n if(kind == 'keys' )return step(0, entry.k);\n if(kind == 'values')return step(0, entry.v);\n return step(0, [entry.k, entry.v]);\n }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true);\n\n // add [@@species], 23.1.2.2, 23.2.2.2\n setSpecies(NAME);\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_collection-strong.js\n// module id = 53\n// module chunks = 0","var isObject = require('./_is-object')\n , document = require('./_global').document\n // in old IE typeof document.createElement is 'object'\n , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n return is ? document.createElement(it) : {};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_dom-create.js\n// module id = 54\n// module chunks = 0","module.exports = !require('./_descriptors') && !require('./_fails')(function(){\n return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_ie8-dom-define.js\n// module id = 55\n// module chunks = 0","'use strict';\nvar create = require('./_object-create')\n , descriptor = require('./_property-desc')\n , setToStringTag = require('./_set-to-string-tag')\n , IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function(){ return this; });\n\nmodule.exports = function(Constructor, NAME, next){\n Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)});\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iter-create.js\n// module id = 56\n// module chunks = 0","exports.f = Object.getOwnPropertySymbols;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-gops.js\n// module id = 57\n// module chunks = 0","var has = require('./_has')\n , toIObject = require('./_to-iobject')\n , arrayIndexOf = require('./_array-includes')(false)\n , IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function(object, names){\n var O = toIObject(object)\n , i = 0\n , result = []\n , key;\n for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while(names.length > i)if(has(O, key = names[i++])){\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-keys-internal.js\n// module id = 58\n// module chunks = 0","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal')\n , enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O){\n return $keys(O, enumBugKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-keys.js\n// module id = 59\n// module chunks = 0","exports.f = {}.propertyIsEnumerable;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-pie.js\n// module id = 60\n// module chunks = 0","// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = require('./_is-object')\n , anObject = require('./_an-object');\nvar check = function(O, proto){\n anObject(O);\n if(!isObject(proto) && proto !== null)throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n function(test, buggy, set){\n try {\n set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);\n set(test, []);\n buggy = !(test instanceof Array);\n } catch(e){ buggy = true; }\n return function setPrototypeOf(O, proto){\n check(O, proto);\n if(buggy)O.__proto__ = proto;\n else set(O, proto);\n return O;\n };\n }({}, false) : undefined),\n check: check\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_set-proto.js\n// module id = 61\n// module chunks = 0","// 7.1.4 ToInteger\nvar ceil = Math.ceil\n , floor = Math.floor;\nmodule.exports = function(it){\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-integer.js\n// module id = 62\n// module chunks = 0","import \"core-js/es6/reflect\";\r\nimport \"core-js/es7/reflect\";\r\nimport \"zone.js/dist/zone\";\r\n\r\n\r\n\r\n/***************************************************************************************************\r\n * APPLICATION IMPORTS\r\n */\r\n\r\n/**\r\n * Date, currency, decimal and percent pipes.\r\n * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10\r\n */\r\n// import 'intl'; // Run `npm install --save intl`.\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/polyfills.ts","require('../modules/es6.reflect.apply');\nrequire('../modules/es6.reflect.construct');\nrequire('../modules/es6.reflect.define-property');\nrequire('../modules/es6.reflect.delete-property');\nrequire('../modules/es6.reflect.enumerate');\nrequire('../modules/es6.reflect.get');\nrequire('../modules/es6.reflect.get-own-property-descriptor');\nrequire('../modules/es6.reflect.get-prototype-of');\nrequire('../modules/es6.reflect.has');\nrequire('../modules/es6.reflect.is-extensible');\nrequire('../modules/es6.reflect.own-keys');\nrequire('../modules/es6.reflect.prevent-extensions');\nrequire('../modules/es6.reflect.set');\nrequire('../modules/es6.reflect.set-prototype-of');\nmodule.exports = require('../modules/_core').Reflect;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/es6/reflect.js\n// module id = 90\n// module chunks = 0","require('../modules/es7.reflect.define-metadata');\nrequire('../modules/es7.reflect.delete-metadata');\nrequire('../modules/es7.reflect.get-metadata');\nrequire('../modules/es7.reflect.get-metadata-keys');\nrequire('../modules/es7.reflect.get-own-metadata');\nrequire('../modules/es7.reflect.get-own-metadata-keys');\nrequire('../modules/es7.reflect.has-metadata');\nrequire('../modules/es7.reflect.has-own-metadata');\nrequire('../modules/es7.reflect.metadata');\nmodule.exports = require('../modules/_core').Reflect;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/es7/reflect.js\n// module id = 91\n// module chunks = 0","var forOf = require('./_for-of');\n\nmodule.exports = function(iter, ITERATOR){\n var result = [];\n forOf(iter, false, result.push, result, ITERATOR);\n return result;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_array-from-iterable.js\n// module id = 92\n// module chunks = 0","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject')\n , toLength = require('./_to-length')\n , toIndex = require('./_to-index');\nmodule.exports = function(IS_INCLUDES){\n return function($this, el, fromIndex){\n var O = toIObject($this)\n , length = toLength(O.length)\n , index = toIndex(fromIndex, length)\n , value;\n // Array#includes uses SameValueZero equality algorithm\n if(IS_INCLUDES && el != el)while(length > index){\n value = O[index++];\n if(value != value)return true;\n // Array#toIndex ignores holes, Array#includes - not\n } else for(;length > index; index++)if(IS_INCLUDES || index in O){\n if(O[index] === el)return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_array-includes.js\n// module id = 93\n// module chunks = 0","var isObject = require('./_is-object')\n , isArray = require('./_is-array')\n , SPECIES = require('./_wks')('species');\n\nmodule.exports = function(original){\n var C;\n if(isArray(original)){\n C = original.constructor;\n // cross-realm fallback\n if(typeof C == 'function' && (C === Array || isArray(C.prototype)))C = undefined;\n if(isObject(C)){\n C = C[SPECIES];\n if(C === null)C = undefined;\n }\n } return C === undefined ? Array : C;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_array-species-constructor.js\n// module id = 94\n// module chunks = 0","// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar speciesConstructor = require('./_array-species-constructor');\n\nmodule.exports = function(original, length){\n return new (speciesConstructor(original))(length);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_array-species-create.js\n// module id = 95\n// module chunks = 0","'use strict';\nvar aFunction = require('./_a-function')\n , isObject = require('./_is-object')\n , invoke = require('./_invoke')\n , arraySlice = [].slice\n , factories = {};\n\nvar construct = function(F, len, args){\n if(!(len in factories)){\n for(var n = [], i = 0; i < len; i++)n[i] = 'a[' + i + ']';\n factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n } return factories[len](F, args);\n};\n\nmodule.exports = Function.bind || function bind(that /*, args... */){\n var fn = aFunction(this)\n , partArgs = arraySlice.call(arguments, 1);\n var bound = function(/* args... */){\n var args = partArgs.concat(arraySlice.call(arguments));\n return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n };\n if(isObject(fn.prototype))bound.prototype = fn.prototype;\n return bound;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_bind.js\n// module id = 96\n// module chunks = 0","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof')\n , TAG = require('./_wks')('toStringTag')\n // ES3 wrong here\n , ARG = cof(function(){ return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function(it, key){\n try {\n return it[key];\n } catch(e){ /* empty */ }\n};\n\nmodule.exports = function(it){\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_classof.js\n// module id = 97\n// module chunks = 0","'use strict';\nvar redefineAll = require('./_redefine-all')\n , getWeak = require('./_meta').getWeak\n , anObject = require('./_an-object')\n , isObject = require('./_is-object')\n , anInstance = require('./_an-instance')\n , forOf = require('./_for-of')\n , createArrayMethod = require('./_array-methods')\n , $has = require('./_has')\n , arrayFind = createArrayMethod(5)\n , arrayFindIndex = createArrayMethod(6)\n , id = 0;\n\n// fallback for uncaught frozen keys\nvar uncaughtFrozenStore = function(that){\n return that._l || (that._l = new UncaughtFrozenStore);\n};\nvar UncaughtFrozenStore = function(){\n this.a = [];\n};\nvar findUncaughtFrozen = function(store, key){\n return arrayFind(store.a, function(it){\n return it[0] === key;\n });\n};\nUncaughtFrozenStore.prototype = {\n get: function(key){\n var entry = findUncaughtFrozen(this, key);\n if(entry)return entry[1];\n },\n has: function(key){\n return !!findUncaughtFrozen(this, key);\n },\n set: function(key, value){\n var entry = findUncaughtFrozen(this, key);\n if(entry)entry[1] = value;\n else this.a.push([key, value]);\n },\n 'delete': function(key){\n var index = arrayFindIndex(this.a, function(it){\n return it[0] === key;\n });\n if(~index)this.a.splice(index, 1);\n return !!~index;\n }\n};\n\nmodule.exports = {\n getConstructor: function(wrapper, NAME, IS_MAP, ADDER){\n var C = wrapper(function(that, iterable){\n anInstance(that, C, NAME, '_i');\n that._i = id++; // collection id\n that._l = undefined; // leak store for uncaught frozen objects\n if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that);\n });\n redefineAll(C.prototype, {\n // 23.3.3.2 WeakMap.prototype.delete(key)\n // 23.4.3.3 WeakSet.prototype.delete(value)\n 'delete': function(key){\n if(!isObject(key))return false;\n var data = getWeak(key);\n if(data === true)return uncaughtFrozenStore(this)['delete'](key);\n return data && $has(data, this._i) && delete data[this._i];\n },\n // 23.3.3.4 WeakMap.prototype.has(key)\n // 23.4.3.4 WeakSet.prototype.has(value)\n has: function has(key){\n if(!isObject(key))return false;\n var data = getWeak(key);\n if(data === true)return uncaughtFrozenStore(this).has(key);\n return data && $has(data, this._i);\n }\n });\n return C;\n },\n def: function(that, key, value){\n var data = getWeak(anObject(key), true);\n if(data === true)uncaughtFrozenStore(that).set(key, value);\n else data[that._i] = value;\n return that;\n },\n ufstore: uncaughtFrozenStore\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_collection-weak.js\n// module id = 98\n// module chunks = 0","module.exports = require('./_global').document && document.documentElement;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_html.js\n// module id = 99\n// module chunks = 0","var isObject = require('./_is-object')\n , setPrototypeOf = require('./_set-proto').set;\nmodule.exports = function(that, target, C){\n var P, S = target.constructor;\n if(S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf){\n setPrototypeOf(that, P);\n } return that;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_inherit-if-required.js\n// module id = 100\n// module chunks = 0","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function(fn, args, that){\n var un = that === undefined;\n switch(args.length){\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_invoke.js\n// module id = 101\n// module chunks = 0","// check on default Array iterator\nvar Iterators = require('./_iterators')\n , ITERATOR = require('./_wks')('iterator')\n , ArrayProto = Array.prototype;\n\nmodule.exports = function(it){\n return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_is-array-iter.js\n// module id = 102\n// module chunks = 0","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg){\n return cof(arg) == 'Array';\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_is-array.js\n// module id = 103\n// module chunks = 0","// call something on iterator step with safe closing on error\nvar anObject = require('./_an-object');\nmodule.exports = function(iterator, fn, value, entries){\n try {\n return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch(e){\n var ret = iterator['return'];\n if(ret !== undefined)anObject(ret.call(iterator));\n throw e;\n }\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iter-call.js\n// module id = 104\n// module chunks = 0","'use strict';\nvar LIBRARY = require('./_library')\n , $export = require('./_export')\n , redefine = require('./_redefine')\n , hide = require('./_hide')\n , has = require('./_has')\n , Iterators = require('./_iterators')\n , $iterCreate = require('./_iter-create')\n , setToStringTag = require('./_set-to-string-tag')\n , getPrototypeOf = require('./_object-gpo')\n , ITERATOR = require('./_wks')('iterator')\n , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`\n , FF_ITERATOR = '@@iterator'\n , KEYS = 'keys'\n , VALUES = 'values';\n\nvar returnThis = function(){ return this; };\n\nmodule.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){\n $iterCreate(Constructor, NAME, next);\n var getMethod = function(kind){\n if(!BUGGY && kind in proto)return proto[kind];\n switch(kind){\n case KEYS: return function keys(){ return new Constructor(this, kind); };\n case VALUES: return function values(){ return new Constructor(this, kind); };\n } return function entries(){ return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator'\n , DEF_VALUES = DEFAULT == VALUES\n , VALUES_BUG = false\n , proto = Base.prototype\n , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]\n , $default = $native || getMethod(DEFAULT)\n , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined\n , $anyNative = NAME == 'Array' ? proto.entries || $native : $native\n , methods, key, IteratorPrototype;\n // Fix native\n if($anyNative){\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base));\n if(IteratorPrototype !== Object.prototype){\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if(DEF_VALUES && $native && $native.name !== VALUES){\n VALUES_BUG = true;\n $default = function values(){ return $native.call(this); };\n }\n // Define iterator\n if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if(DEFAULT){\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if(FORCED)for(key in methods){\n if(!(key in proto))redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iter-define.js\n// module id = 105\n// module chunks = 0","var ITERATOR = require('./_wks')('iterator')\n , SAFE_CLOSING = false;\n\ntry {\n var riter = [7][ITERATOR]();\n riter['return'] = function(){ SAFE_CLOSING = true; };\n Array.from(riter, function(){ throw 2; });\n} catch(e){ /* empty */ }\n\nmodule.exports = function(exec, skipClosing){\n if(!skipClosing && !SAFE_CLOSING)return false;\n var safe = false;\n try {\n var arr = [7]\n , iter = arr[ITERATOR]();\n iter.next = function(){ return {done: safe = true}; };\n arr[ITERATOR] = function(){ return iter; };\n exec(arr);\n } catch(e){ /* empty */ }\n return safe;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iter-detect.js\n// module id = 106\n// module chunks = 0","module.exports = function(done, value){\n return {value: value, done: !!done};\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_iter-step.js\n// module id = 107\n// module chunks = 0","module.exports = false;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_library.js\n// module id = 108\n// module chunks = 0","'use strict';\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = require('./_object-keys')\n , gOPS = require('./_object-gops')\n , pIE = require('./_object-pie')\n , toObject = require('./_to-object')\n , IObject = require('./_iobject')\n , $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || require('./_fails')(function(){\n var A = {}\n , B = {}\n , S = Symbol()\n , K = 'abcdefghijklmnopqrst';\n A[S] = 7;\n K.split('').forEach(function(k){ B[k] = k; });\n return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source){ // eslint-disable-line no-unused-vars\n var T = toObject(target)\n , aLen = arguments.length\n , index = 1\n , getSymbols = gOPS.f\n , isEnum = pIE.f;\n while(aLen > index){\n var S = IObject(arguments[index++])\n , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S)\n , length = keys.length\n , j = 0\n , key;\n while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key];\n } return T;\n} : $assign;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-assign.js\n// module id = 109\n// module chunks = 0","var dP = require('./_object-dp')\n , anObject = require('./_an-object')\n , getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties){\n anObject(O);\n var keys = getKeys(Properties)\n , length = keys.length\n , i = 0\n , P;\n while(length > i)dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-dps.js\n// module id = 110\n// module chunks = 0","// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = require('./_object-keys-internal')\n , hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O){\n return $keys(O, hiddenKeys);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_object-gopn.js\n// module id = 111\n// module chunks = 0","// all object keys, includes non-enumerable and symbols\nvar gOPN = require('./_object-gopn')\n , gOPS = require('./_object-gops')\n , anObject = require('./_an-object')\n , Reflect = require('./_global').Reflect;\nmodule.exports = Reflect && Reflect.ownKeys || function ownKeys(it){\n var keys = gOPN.f(anObject(it))\n , getSymbols = gOPS.f;\n return getSymbols ? keys.concat(getSymbols(it)) : keys;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_own-keys.js\n// module id = 112\n// module chunks = 0","'use strict';\nvar global = require('./_global')\n , dP = require('./_object-dp')\n , DESCRIPTORS = require('./_descriptors')\n , SPECIES = require('./_wks')('species');\n\nmodule.exports = function(KEY){\n var C = global[KEY];\n if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, {\n configurable: true,\n get: function(){ return this; }\n });\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_set-species.js\n// module id = 113\n// module chunks = 0","var toInteger = require('./_to-integer')\n , max = Math.max\n , min = Math.min;\nmodule.exports = function(index, length){\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/_to-index.js\n// module id = 114\n// module chunks = 0","var classof = require('./_classof')\n , ITERATOR = require('./_wks')('iterator')\n , Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function(it){\n if(it != undefined)return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/core.get-iterator-method.js\n// module id = 115\n// module chunks = 0","'use strict';\nvar strong = require('./_collection-strong');\n\n// 23.1 Map Objects\nmodule.exports = require('./_collection')('Map', function(get){\n return function Map(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n // 23.1.3.6 Map.prototype.get(key)\n get: function get(key){\n var entry = strong.getEntry(this, key);\n return entry && entry.v;\n },\n // 23.1.3.9 Map.prototype.set(key, value)\n set: function set(key, value){\n return strong.def(this, key === 0 ? 0 : key, value);\n }\n}, strong, true);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.map.js\n// module id = 116\n// module chunks = 0","// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)\nvar $export = require('./_export')\n , aFunction = require('./_a-function')\n , anObject = require('./_an-object')\n , rApply = (require('./_global').Reflect || {}).apply\n , fApply = Function.apply;\n// MS Edge argumentsList argument is optional\n$export($export.S + $export.F * !require('./_fails')(function(){\n rApply(function(){});\n}), 'Reflect', {\n apply: function apply(target, thisArgument, argumentsList){\n var T = aFunction(target)\n , L = anObject(argumentsList);\n return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.apply.js\n// module id = 117\n// module chunks = 0","// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])\nvar $export = require('./_export')\n , create = require('./_object-create')\n , aFunction = require('./_a-function')\n , anObject = require('./_an-object')\n , isObject = require('./_is-object')\n , fails = require('./_fails')\n , bind = require('./_bind')\n , rConstruct = (require('./_global').Reflect || {}).construct;\n\n// MS Edge supports only 2 arguments and argumentsList argument is optional\n// FF Nightly sets third argument as `new.target`, but does not create `this` from it\nvar NEW_TARGET_BUG = fails(function(){\n function F(){}\n return !(rConstruct(function(){}, [], F) instanceof F);\n});\nvar ARGS_BUG = !fails(function(){\n rConstruct(function(){});\n});\n\n$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {\n construct: function construct(Target, args /*, newTarget*/){\n aFunction(Target);\n anObject(args);\n var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);\n if(ARGS_BUG && !NEW_TARGET_BUG)return rConstruct(Target, args, newTarget);\n if(Target == newTarget){\n // w/o altered newTarget, optimization for 0-4 arguments\n switch(args.length){\n case 0: return new Target;\n case 1: return new Target(args[0]);\n case 2: return new Target(args[0], args[1]);\n case 3: return new Target(args[0], args[1], args[2]);\n case 4: return new Target(args[0], args[1], args[2], args[3]);\n }\n // w/o altered newTarget, lot of arguments case\n var $args = [null];\n $args.push.apply($args, args);\n return new (bind.apply(Target, $args));\n }\n // with altered newTarget, not support built-in constructors\n var proto = newTarget.prototype\n , instance = create(isObject(proto) ? proto : Object.prototype)\n , result = Function.apply.call(Target, instance, args);\n return isObject(result) ? result : instance;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.construct.js\n// module id = 118\n// module chunks = 0","// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)\nvar dP = require('./_object-dp')\n , $export = require('./_export')\n , anObject = require('./_an-object')\n , toPrimitive = require('./_to-primitive');\n\n// MS Edge has broken Reflect.defineProperty - throwing instead of returning false\n$export($export.S + $export.F * require('./_fails')(function(){\n Reflect.defineProperty(dP.f({}, 1, {value: 1}), 1, {value: 2});\n}), 'Reflect', {\n defineProperty: function defineProperty(target, propertyKey, attributes){\n anObject(target);\n propertyKey = toPrimitive(propertyKey, true);\n anObject(attributes);\n try {\n dP.f(target, propertyKey, attributes);\n return true;\n } catch(e){\n return false;\n }\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.define-property.js\n// module id = 119\n// module chunks = 0","// 26.1.4 Reflect.deleteProperty(target, propertyKey)\nvar $export = require('./_export')\n , gOPD = require('./_object-gopd').f\n , anObject = require('./_an-object');\n\n$export($export.S, 'Reflect', {\n deleteProperty: function deleteProperty(target, propertyKey){\n var desc = gOPD(anObject(target), propertyKey);\n return desc && !desc.configurable ? false : delete target[propertyKey];\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.delete-property.js\n// module id = 120\n// module chunks = 0","'use strict';\n// 26.1.5 Reflect.enumerate(target)\nvar $export = require('./_export')\n , anObject = require('./_an-object');\nvar Enumerate = function(iterated){\n this._t = anObject(iterated); // target\n this._i = 0; // next index\n var keys = this._k = [] // keys\n , key;\n for(key in iterated)keys.push(key);\n};\nrequire('./_iter-create')(Enumerate, 'Object', function(){\n var that = this\n , keys = that._k\n , key;\n do {\n if(that._i >= keys.length)return {value: undefined, done: true};\n } while(!((key = keys[that._i++]) in that._t));\n return {value: key, done: false};\n});\n\n$export($export.S, 'Reflect', {\n enumerate: function enumerate(target){\n return new Enumerate(target);\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.enumerate.js\n// module id = 121\n// module chunks = 0","// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)\nvar gOPD = require('./_object-gopd')\n , $export = require('./_export')\n , anObject = require('./_an-object');\n\n$export($export.S, 'Reflect', {\n getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey){\n return gOPD.f(anObject(target), propertyKey);\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.get-own-property-descriptor.js\n// module id = 122\n// module chunks = 0","// 26.1.8 Reflect.getPrototypeOf(target)\nvar $export = require('./_export')\n , getProto = require('./_object-gpo')\n , anObject = require('./_an-object');\n\n$export($export.S, 'Reflect', {\n getPrototypeOf: function getPrototypeOf(target){\n return getProto(anObject(target));\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.get-prototype-of.js\n// module id = 123\n// module chunks = 0","// 26.1.6 Reflect.get(target, propertyKey [, receiver])\nvar gOPD = require('./_object-gopd')\n , getPrototypeOf = require('./_object-gpo')\n , has = require('./_has')\n , $export = require('./_export')\n , isObject = require('./_is-object')\n , anObject = require('./_an-object');\n\nfunction get(target, propertyKey/*, receiver*/){\n var receiver = arguments.length < 3 ? target : arguments[2]\n , desc, proto;\n if(anObject(target) === receiver)return target[propertyKey];\n if(desc = gOPD.f(target, propertyKey))return has(desc, 'value')\n ? desc.value\n : desc.get !== undefined\n ? desc.get.call(receiver)\n : undefined;\n if(isObject(proto = getPrototypeOf(target)))return get(proto, propertyKey, receiver);\n}\n\n$export($export.S, 'Reflect', {get: get});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.get.js\n// module id = 124\n// module chunks = 0","// 26.1.9 Reflect.has(target, propertyKey)\nvar $export = require('./_export');\n\n$export($export.S, 'Reflect', {\n has: function has(target, propertyKey){\n return propertyKey in target;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.has.js\n// module id = 125\n// module chunks = 0","// 26.1.10 Reflect.isExtensible(target)\nvar $export = require('./_export')\n , anObject = require('./_an-object')\n , $isExtensible = Object.isExtensible;\n\n$export($export.S, 'Reflect', {\n isExtensible: function isExtensible(target){\n anObject(target);\n return $isExtensible ? $isExtensible(target) : true;\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.is-extensible.js\n// module id = 126\n// module chunks = 0","// 26.1.11 Reflect.ownKeys(target)\nvar $export = require('./_export');\n\n$export($export.S, 'Reflect', {ownKeys: require('./_own-keys')});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.own-keys.js\n// module id = 127\n// module chunks = 0","// 26.1.12 Reflect.preventExtensions(target)\nvar $export = require('./_export')\n , anObject = require('./_an-object')\n , $preventExtensions = Object.preventExtensions;\n\n$export($export.S, 'Reflect', {\n preventExtensions: function preventExtensions(target){\n anObject(target);\n try {\n if($preventExtensions)$preventExtensions(target);\n return true;\n } catch(e){\n return false;\n }\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.prevent-extensions.js\n// module id = 128\n// module chunks = 0","// 26.1.14 Reflect.setPrototypeOf(target, proto)\nvar $export = require('./_export')\n , setProto = require('./_set-proto');\n\nif(setProto)$export($export.S, 'Reflect', {\n setPrototypeOf: function setPrototypeOf(target, proto){\n setProto.check(target, proto);\n try {\n setProto.set(target, proto);\n return true;\n } catch(e){\n return false;\n }\n }\n});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.set-prototype-of.js\n// module id = 129\n// module chunks = 0","// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])\nvar dP = require('./_object-dp')\n , gOPD = require('./_object-gopd')\n , getPrototypeOf = require('./_object-gpo')\n , has = require('./_has')\n , $export = require('./_export')\n , createDesc = require('./_property-desc')\n , anObject = require('./_an-object')\n , isObject = require('./_is-object');\n\nfunction set(target, propertyKey, V/*, receiver*/){\n var receiver = arguments.length < 4 ? target : arguments[3]\n , ownDesc = gOPD.f(anObject(target), propertyKey)\n , existingDescriptor, proto;\n if(!ownDesc){\n if(isObject(proto = getPrototypeOf(target))){\n return set(proto, propertyKey, V, receiver);\n }\n ownDesc = createDesc(0);\n }\n if(has(ownDesc, 'value')){\n if(ownDesc.writable === false || !isObject(receiver))return false;\n existingDescriptor = gOPD.f(receiver, propertyKey) || createDesc(0);\n existingDescriptor.value = V;\n dP.f(receiver, propertyKey, existingDescriptor);\n return true;\n }\n return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);\n}\n\n$export($export.S, 'Reflect', {set: set});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.reflect.set.js\n// module id = 130\n// module chunks = 0","'use strict';\nvar strong = require('./_collection-strong');\n\n// 23.2 Set Objects\nmodule.exports = require('./_collection')('Set', function(get){\n return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n // 23.2.3.1 Set.prototype.add(value)\n add: function add(value){\n return strong.def(this, value = value === 0 ? 0 : value, value);\n }\n}, strong);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.set.js\n// module id = 131\n// module chunks = 0","'use strict';\nvar each = require('./_array-methods')(0)\n , redefine = require('./_redefine')\n , meta = require('./_meta')\n , assign = require('./_object-assign')\n , weak = require('./_collection-weak')\n , isObject = require('./_is-object')\n , getWeak = meta.getWeak\n , isExtensible = Object.isExtensible\n , uncaughtFrozenStore = weak.ufstore\n , tmp = {}\n , InternalMap;\n\nvar wrapper = function(get){\n return function WeakMap(){\n return get(this, arguments.length > 0 ? arguments[0] : undefined);\n };\n};\n\nvar methods = {\n // 23.3.3.3 WeakMap.prototype.get(key)\n get: function get(key){\n if(isObject(key)){\n var data = getWeak(key);\n if(data === true)return uncaughtFrozenStore(this).get(key);\n return data ? data[this._i] : undefined;\n }\n },\n // 23.3.3.5 WeakMap.prototype.set(key, value)\n set: function set(key, value){\n return weak.def(this, key, value);\n }\n};\n\n// 23.3 WeakMap Objects\nvar $WeakMap = module.exports = require('./_collection')('WeakMap', wrapper, methods, weak, true, true);\n\n// IE11 WeakMap frozen keys fix\nif(new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7){\n InternalMap = weak.getConstructor(wrapper);\n assign(InternalMap.prototype, methods);\n meta.NEED = true;\n each(['delete', 'has', 'get', 'set'], function(key){\n var proto = $WeakMap.prototype\n , method = proto[key];\n redefine(proto, key, function(a, b){\n // store frozen objects on internal weakmap shim\n if(isObject(a) && !isExtensible(a)){\n if(!this._f)this._f = new InternalMap;\n var result = this._f[key](a, b);\n return key == 'set' ? this : result;\n // store all the rest on native weakmap\n } return method.call(this, a, b);\n });\n });\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es6.weak-map.js\n// module id = 132\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , toMetaKey = metadata.key\n , ordinaryDefineOwnMetadata = metadata.set;\n\nmetadata.exp({defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey){\n ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.define-metadata.js\n// module id = 133\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , toMetaKey = metadata.key\n , getOrCreateMetadataMap = metadata.map\n , store = metadata.store;\n\nmetadata.exp({deleteMetadata: function deleteMetadata(metadataKey, target /*, targetKey */){\n var targetKey = arguments.length < 3 ? undefined : toMetaKey(arguments[2])\n , metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);\n if(metadataMap === undefined || !metadataMap['delete'](metadataKey))return false;\n if(metadataMap.size)return true;\n var targetMetadata = store.get(target);\n targetMetadata['delete'](targetKey);\n return !!targetMetadata.size || store['delete'](target);\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.delete-metadata.js\n// module id = 134\n// module chunks = 0","var Set = require('./es6.set')\n , from = require('./_array-from-iterable')\n , metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , getPrototypeOf = require('./_object-gpo')\n , ordinaryOwnMetadataKeys = metadata.keys\n , toMetaKey = metadata.key;\n\nvar ordinaryMetadataKeys = function(O, P){\n var oKeys = ordinaryOwnMetadataKeys(O, P)\n , parent = getPrototypeOf(O);\n if(parent === null)return oKeys;\n var pKeys = ordinaryMetadataKeys(parent, P);\n return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;\n};\n\nmetadata.exp({getMetadataKeys: function getMetadataKeys(target /*, targetKey */){\n return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.get-metadata-keys.js\n// module id = 135\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , getPrototypeOf = require('./_object-gpo')\n , ordinaryHasOwnMetadata = metadata.has\n , ordinaryGetOwnMetadata = metadata.get\n , toMetaKey = metadata.key;\n\nvar ordinaryGetMetadata = function(MetadataKey, O, P){\n var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n if(hasOwn)return ordinaryGetOwnMetadata(MetadataKey, O, P);\n var parent = getPrototypeOf(O);\n return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;\n};\n\nmetadata.exp({getMetadata: function getMetadata(metadataKey, target /*, targetKey */){\n return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.get-metadata.js\n// module id = 136\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , ordinaryOwnMetadataKeys = metadata.keys\n , toMetaKey = metadata.key;\n\nmetadata.exp({getOwnMetadataKeys: function getOwnMetadataKeys(target /*, targetKey */){\n return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.get-own-metadata-keys.js\n// module id = 137\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , ordinaryGetOwnMetadata = metadata.get\n , toMetaKey = metadata.key;\n\nmetadata.exp({getOwnMetadata: function getOwnMetadata(metadataKey, target /*, targetKey */){\n return ordinaryGetOwnMetadata(metadataKey, anObject(target)\n , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.get-own-metadata.js\n// module id = 138\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , getPrototypeOf = require('./_object-gpo')\n , ordinaryHasOwnMetadata = metadata.has\n , toMetaKey = metadata.key;\n\nvar ordinaryHasMetadata = function(MetadataKey, O, P){\n var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n if(hasOwn)return true;\n var parent = getPrototypeOf(O);\n return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;\n};\n\nmetadata.exp({hasMetadata: function hasMetadata(metadataKey, target /*, targetKey */){\n return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.has-metadata.js\n// module id = 139\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , ordinaryHasOwnMetadata = metadata.has\n , toMetaKey = metadata.key;\n\nmetadata.exp({hasOwnMetadata: function hasOwnMetadata(metadataKey, target /*, targetKey */){\n return ordinaryHasOwnMetadata(metadataKey, anObject(target)\n , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.has-own-metadata.js\n// module id = 140\n// module chunks = 0","var metadata = require('./_metadata')\n , anObject = require('./_an-object')\n , aFunction = require('./_a-function')\n , toMetaKey = metadata.key\n , ordinaryDefineOwnMetadata = metadata.set;\n\nmetadata.exp({metadata: function metadata(metadataKey, metadataValue){\n return function decorator(target, targetKey){\n ordinaryDefineOwnMetadata(\n metadataKey, metadataValue,\n (targetKey !== undefined ? anObject : aFunction)(target),\n toMetaKey(targetKey)\n );\n };\n}});\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/core-js/modules/es7.reflect.metadata.js\n// module id = 141\n// module chunks = 0","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/process/browser.js\n// module id = 148\n// module chunks = 0","/**\n* @license\n* Copyright Google Inc. All Rights Reserved.\n*\n* Use of this source code is governed by an MIT-style license that can be\n* found in the LICENSE file at https://angular.io/license\n*/\n(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(factory());\n}(this, (function () { 'use strict';\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nvar Zone$1 = (function (global) {\n if (global['Zone']) {\n throw new Error('Zone already loaded.');\n }\n var NO_ZONE = { name: 'NO ZONE' };\n var notScheduled = 'notScheduled', scheduling = 'scheduling', scheduled = 'scheduled', running = 'running', canceling = 'canceling', unknown = 'unknown';\n var microTask = 'microTask', macroTask = 'macroTask', eventTask = 'eventTask';\n var Zone = (function () {\n function Zone(parent, zoneSpec) {\n this._properties = null;\n this._parent = parent;\n this._name = zoneSpec ? zoneSpec.name || 'unnamed' : '';\n this._properties = zoneSpec && zoneSpec.properties || {};\n this._zoneDelegate =\n new ZoneDelegate(this, this._parent && this._parent._zoneDelegate, zoneSpec);\n }\n Zone.assertZonePatched = function () {\n if (global.Promise !== ZoneAwarePromise) {\n throw new Error('Zone.js has detected that ZoneAwarePromise `(window|global).Promise` ' +\n 'has been overwritten.\\n' +\n 'Most likely cause is that a Promise polyfill has been loaded ' +\n 'after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. ' +\n 'If you must load one, do so before loading zone.js.)');\n }\n };\n Object.defineProperty(Zone, \"root\", {\n get: function () {\n var zone = Zone.current;\n while (zone.parent) {\n zone = zone.parent;\n }\n return zone;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(Zone, \"current\", {\n get: function () {\n return _currentZoneFrame.zone;\n },\n enumerable: true,\n configurable: true\n });\n \n Object.defineProperty(Zone, \"currentTask\", {\n get: function () {\n return _currentTask;\n },\n enumerable: true,\n configurable: true\n });\n \n Object.defineProperty(Zone.prototype, \"parent\", {\n get: function () {\n return this._parent;\n },\n enumerable: true,\n configurable: true\n });\n \n Object.defineProperty(Zone.prototype, \"name\", {\n get: function () {\n return this._name;\n },\n enumerable: true,\n configurable: true\n });\n \n Zone.prototype.get = function (key) {\n var zone = this.getZoneWith(key);\n if (zone)\n return zone._properties[key];\n };\n Zone.prototype.getZoneWith = function (key) {\n var current = this;\n while (current) {\n if (current._properties.hasOwnProperty(key)) {\n return current;\n }\n current = current._parent;\n }\n return null;\n };\n Zone.prototype.fork = function (zoneSpec) {\n if (!zoneSpec)\n throw new Error('ZoneSpec required!');\n return this._zoneDelegate.fork(this, zoneSpec);\n };\n Zone.prototype.wrap = function (callback, source) {\n if (typeof callback !== 'function') {\n throw new Error('Expecting function got: ' + callback);\n }\n var _callback = this._zoneDelegate.intercept(this, callback, source);\n var zone = this;\n return function () {\n return zone.runGuarded(_callback, this, arguments, source);\n };\n };\n Zone.prototype.run = function (callback, applyThis, applyArgs, source) {\n if (applyThis === void 0) { applyThis = undefined; }\n if (applyArgs === void 0) { applyArgs = null; }\n if (source === void 0) { source = null; }\n _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);\n try {\n return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);\n }\n finally {\n _currentZoneFrame = _currentZoneFrame.parent;\n }\n };\n Zone.prototype.runGuarded = function (callback, applyThis, applyArgs, source) {\n if (applyThis === void 0) { applyThis = null; }\n if (applyArgs === void 0) { applyArgs = null; }\n if (source === void 0) { source = null; }\n _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);\n try {\n try {\n return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);\n }\n catch (error) {\n if (this._zoneDelegate.handleError(this, error)) {\n throw error;\n }\n }\n }\n finally {\n _currentZoneFrame = _currentZoneFrame.parent;\n }\n };\n Zone.prototype.runTask = function (task, applyThis, applyArgs) {\n if (task.zone != this)\n throw new Error('A task can only be run in the zone of creation! (Creation: ' +\n (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');\n var reEntryGuard = task.state != running;\n reEntryGuard && task._transitionTo(running, scheduled);\n task.runCount++;\n var previousTask = _currentTask;\n _currentTask = task;\n _currentZoneFrame = new ZoneFrame(_currentZoneFrame, this);\n try {\n if (task.type == macroTask && task.data && !task.data.isPeriodic) {\n task.cancelFn = null;\n }\n try {\n return this._zoneDelegate.invokeTask(this, task, applyThis, applyArgs);\n }\n catch (error) {\n if (this._zoneDelegate.handleError(this, error)) {\n throw error;\n }\n }\n }\n finally {\n // if the task's state is notScheduled or unknown, then it has already been cancelled\n // we should not reset the state to scheduled\n if (task.state !== notScheduled && task.state !== unknown) {\n if (task.type == eventTask || (task.data && task.data.isPeriodic)) {\n reEntryGuard && task._transitionTo(scheduled, running);\n }\n else {\n task.runCount = 0;\n this._updateTaskCount(task, -1);\n reEntryGuard &&\n task._transitionTo(notScheduled, running, notScheduled);\n }\n }\n _currentZoneFrame = _currentZoneFrame.parent;\n _currentTask = previousTask;\n }\n };\n Zone.prototype.scheduleTask = function (task) {\n if (task.zone && task.zone !== this) {\n // check if the task was rescheduled, the newZone\n // should not be the children of the original zone\n var newZone = this;\n while (newZone) {\n if (newZone === task.zone) {\n throw Error(\"can not reschedule task to \" + this\n .name + \" which is descendants of the original zone \" + task.zone.name);\n }\n newZone = newZone.parent;\n }\n }\n task._transitionTo(scheduling, notScheduled);\n var zoneDelegates = [];\n task._zoneDelegates = zoneDelegates;\n task._zone = this;\n try {\n task = this._zoneDelegate.scheduleTask(this, task);\n }\n catch (err) {\n // should set task's state to unknown when scheduleTask throw error\n // because the err may from reschedule, so the fromState maybe notScheduled\n task._transitionTo(unknown, scheduling, notScheduled);\n // TODO: @JiaLiPassion, should we check the result from handleError?\n this._zoneDelegate.handleError(this, err);\n throw err;\n }\n if (task._zoneDelegates === zoneDelegates) {\n // we have to check because internally the delegate can reschedule the task.\n this._updateTaskCount(task, 1);\n }\n if (task.state == scheduling) {\n task._transitionTo(scheduled, scheduling);\n }\n return task;\n };\n Zone.prototype.scheduleMicroTask = function (source, callback, data, customSchedule) {\n return this.scheduleTask(new ZoneTask(microTask, source, callback, data, customSchedule, null));\n };\n Zone.prototype.scheduleMacroTask = function (source, callback, data, customSchedule, customCancel) {\n return this.scheduleTask(new ZoneTask(macroTask, source, callback, data, customSchedule, customCancel));\n };\n Zone.prototype.scheduleEventTask = function (source, callback, data, customSchedule, customCancel) {\n return this.scheduleTask(new ZoneTask(eventTask, source, callback, data, customSchedule, customCancel));\n };\n Zone.prototype.cancelTask = function (task) {\n if (task.zone != this)\n throw new Error('A task can only be cancelled in the zone of creation! (Creation: ' +\n (task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');\n task._transitionTo(canceling, scheduled, running);\n try {\n this._zoneDelegate.cancelTask(this, task);\n }\n catch (err) {\n // if error occurs when cancelTask, transit the state to unknown\n task._transitionTo(unknown, canceling);\n this._zoneDelegate.handleError(this, err);\n throw err;\n }\n this._updateTaskCount(task, -1);\n task._transitionTo(notScheduled, canceling);\n task.runCount = 0;\n return task;\n };\n Zone.prototype._updateTaskCount = function (task, count) {\n var zoneDelegates = task._zoneDelegates;\n if (count == -1) {\n task._zoneDelegates = null;\n }\n for (var i = 0; i < zoneDelegates.length; i++) {\n zoneDelegates[i]._updateTaskCount(task.type, count);\n }\n };\n return Zone;\n }());\n Zone.__symbol__ = __symbol__;\n var DELEGATE_ZS = {\n name: '',\n onHasTask: function (delegate, _, target, hasTaskState) {\n return delegate.hasTask(target, hasTaskState);\n },\n onScheduleTask: function (delegate, _, target, task) {\n return delegate.scheduleTask(target, task);\n },\n onInvokeTask: function (delegate, _, target, task, applyThis, applyArgs) { return delegate.invokeTask(target, task, applyThis, applyArgs); },\n onCancelTask: function (delegate, _, target, task) {\n return delegate.cancelTask(target, task);\n }\n };\n var ZoneDelegate = (function () {\n function ZoneDelegate(zone, parentDelegate, zoneSpec) {\n this._taskCounts = { 'microTask': 0, 'macroTask': 0, 'eventTask': 0 };\n this.zone = zone;\n this._parentDelegate = parentDelegate;\n this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate._forkZS);\n this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate._forkDlgt);\n this._forkCurrZone = zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate.zone);\n this._interceptZS =\n zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate._interceptZS);\n this._interceptDlgt =\n zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate._interceptDlgt);\n this._interceptCurrZone =\n zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate.zone);\n this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate._invokeZS);\n this._invokeDlgt =\n zoneSpec && (zoneSpec.onInvoke ? parentDelegate : parentDelegate._invokeDlgt);\n this._invokeCurrZone = zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate.zone);\n this._handleErrorZS =\n zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate._handleErrorZS);\n this._handleErrorDlgt =\n zoneSpec && (zoneSpec.onHandleError ? parentDelegate : parentDelegate._handleErrorDlgt);\n this._handleErrorCurrZone =\n zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate.zone);\n this._scheduleTaskZS =\n zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate._scheduleTaskZS);\n this._scheduleTaskDlgt =\n zoneSpec && (zoneSpec.onScheduleTask ? parentDelegate : parentDelegate._scheduleTaskDlgt);\n this._scheduleTaskCurrZone =\n zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate.zone);\n this._invokeTaskZS =\n zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate._invokeTaskZS);\n this._invokeTaskDlgt =\n zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate : parentDelegate._invokeTaskDlgt);\n this._invokeTaskCurrZone =\n zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate.zone);\n this._cancelTaskZS =\n zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate._cancelTaskZS);\n this._cancelTaskDlgt =\n zoneSpec && (zoneSpec.onCancelTask ? parentDelegate : parentDelegate._cancelTaskDlgt);\n this._cancelTaskCurrZone =\n zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate.zone);\n this._hasTaskZS = null;\n this._hasTaskDlgt = null;\n this._hasTaskDlgtOwner = null;\n this._hasTaskCurrZone = null;\n var zoneSpecHasTask = zoneSpec && zoneSpec.onHasTask;\n var parentHasTask = parentDelegate && parentDelegate._hasTaskZS;\n if (zoneSpecHasTask || parentHasTask) {\n // If we need to report hasTask, than this ZS needs to do ref counting on tasks. In such\n // a case all task related interceptors must go through this ZD. We can't short circuit it.\n this._hasTaskZS = zoneSpecHasTask ? zoneSpec : DELEGATE_ZS;\n this._hasTaskDlgt = parentDelegate;\n this._hasTaskDlgtOwner = this;\n this._hasTaskCurrZone = zone;\n if (!zoneSpec.onScheduleTask) {\n this._scheduleTaskZS = DELEGATE_ZS;\n this._scheduleTaskDlgt = parentDelegate;\n this._scheduleTaskCurrZone = this.zone;\n }\n if (!zoneSpec.onInvokeTask) {\n this._invokeTaskZS = DELEGATE_ZS;\n this._invokeTaskDlgt = parentDelegate;\n this._invokeTaskCurrZone = this.zone;\n }\n if (!zoneSpec.onCancelTask) {\n this._cancelTaskZS = DELEGATE_ZS;\n this._cancelTaskDlgt = parentDelegate;\n this._cancelTaskCurrZone = this.zone;\n }\n }\n }\n ZoneDelegate.prototype.fork = function (targetZone, zoneSpec) {\n return this._forkZS ? this._forkZS.onFork(this._forkDlgt, this.zone, targetZone, zoneSpec) :\n new Zone(targetZone, zoneSpec);\n };\n ZoneDelegate.prototype.intercept = function (targetZone, callback, source) {\n return this._interceptZS ?\n this._interceptZS.onIntercept(this._interceptDlgt, this._interceptCurrZone, targetZone, callback, source) :\n callback;\n };\n ZoneDelegate.prototype.invoke = function (targetZone, callback, applyThis, applyArgs, source) {\n return this._invokeZS ?\n this._invokeZS.onInvoke(this._invokeDlgt, this._invokeCurrZone, targetZone, callback, applyThis, applyArgs, source) :\n callback.apply(applyThis, applyArgs);\n };\n ZoneDelegate.prototype.handleError = function (targetZone, error) {\n return this._handleErrorZS ?\n this._handleErrorZS.onHandleError(this._handleErrorDlgt, this._handleErrorCurrZone, targetZone, error) :\n true;\n };\n ZoneDelegate.prototype.scheduleTask = function (targetZone, task) {\n var returnTask = task;\n if (this._scheduleTaskZS) {\n if (this._hasTaskZS) {\n returnTask._zoneDelegates.push(this._hasTaskDlgtOwner);\n }\n returnTask = this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt, this._scheduleTaskCurrZone, targetZone, task);\n if (!returnTask)\n returnTask = task;\n }\n else {\n if (task.scheduleFn) {\n task.scheduleFn(task);\n }\n else if (task.type == microTask) {\n scheduleMicroTask(task);\n }\n else {\n throw new Error('Task is missing scheduleFn.');\n }\n }\n return returnTask;\n };\n ZoneDelegate.prototype.invokeTask = function (targetZone, task, applyThis, applyArgs) {\n return this._invokeTaskZS ?\n this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt, this._invokeTaskCurrZone, targetZone, task, applyThis, applyArgs) :\n task.callback.apply(applyThis, applyArgs);\n };\n ZoneDelegate.prototype.cancelTask = function (targetZone, task) {\n var value;\n if (this._cancelTaskZS) {\n value = this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt, this._cancelTaskCurrZone, targetZone, task);\n }\n else {\n if (!task.cancelFn) {\n throw Error('Task is not cancelable');\n }\n value = task.cancelFn(task);\n }\n return value;\n };\n ZoneDelegate.prototype.hasTask = function (targetZone, isEmpty) {\n // hasTask should not throw error so other ZoneDelegate\n // can still trigger hasTask callback\n try {\n return this._hasTaskZS &&\n this._hasTaskZS.onHasTask(this._hasTaskDlgt, this._hasTaskCurrZone, targetZone, isEmpty);\n }\n catch (err) {\n }\n };\n ZoneDelegate.prototype._updateTaskCount = function (type, count) {\n var counts = this._taskCounts;\n var prev = counts[type];\n var next = counts[type] = prev + count;\n if (next < 0) {\n throw new Error('More tasks executed then were scheduled.');\n }\n if (prev == 0 || next == 0) {\n var isEmpty = {\n microTask: counts.microTask > 0,\n macroTask: counts.macroTask > 0,\n eventTask: counts.eventTask > 0,\n change: type\n };\n // TODO(misko): what should happen if it throws?\n this.hasTask(this.zone, isEmpty);\n }\n };\n return ZoneDelegate;\n }());\n var ZoneTask = (function () {\n function ZoneTask(type, source, callback, options, scheduleFn, cancelFn) {\n this._zone = null;\n this.runCount = 0;\n this._zoneDelegates = null;\n this._state = 'notScheduled';\n this.type = type;\n this.source = source;\n this.data = options;\n this.scheduleFn = scheduleFn;\n this.cancelFn = cancelFn;\n this.callback = callback;\n var self = this;\n this.invoke = function () {\n _numberOfNestedTaskFrames++;\n try {\n self.runCount++;\n return self.zone.runTask(self, this, arguments);\n }\n finally {\n if (_numberOfNestedTaskFrames == 1) {\n drainMicroTaskQueue();\n }\n _numberOfNestedTaskFrames--;\n }\n };\n }\n Object.defineProperty(ZoneTask.prototype, \"zone\", {\n get: function () {\n return this._zone;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ZoneTask.prototype, \"state\", {\n get: function () {\n return this._state;\n },\n enumerable: true,\n configurable: true\n });\n ZoneTask.prototype.cancelScheduleRequest = function () {\n this._transitionTo(notScheduled, scheduling);\n };\n ZoneTask.prototype._transitionTo = function (toState, fromState1, fromState2) {\n if (this._state === fromState1 || this._state === fromState2) {\n this._state = toState;\n if (toState == notScheduled) {\n this._zoneDelegates = null;\n }\n }\n else {\n throw new Error(this.type + \" '\" + this.source + \"': can not transition to '\" + toState + \"', expecting state '\" + fromState1 + \"'\" + (fromState2 ?\n ' or \\'' + fromState2 + '\\'' :\n '') + \", was '\" + this._state + \"'.\");\n }\n };\n ZoneTask.prototype.toString = function () {\n if (this.data && typeof this.data.handleId !== 'undefined') {\n return this.data.handleId;\n }\n else {\n return Object.prototype.toString.call(this);\n }\n };\n // add toJSON method to prevent cyclic error when\n // call JSON.stringify(zoneTask)\n ZoneTask.prototype.toJSON = function () {\n return {\n type: this.type,\n state: this.state,\n source: this.source,\n data: this.data,\n zone: this.zone.name,\n invoke: this.invoke,\n scheduleFn: this.scheduleFn,\n cancelFn: this.cancelFn,\n runCount: this.runCount,\n callback: this.callback\n };\n };\n return ZoneTask;\n }());\n var ZoneFrame = (function () {\n function ZoneFrame(parent, zone) {\n this.parent = parent;\n this.zone = zone;\n }\n return ZoneFrame;\n }());\n function __symbol__(name) {\n return '__zone_symbol__' + name;\n }\n \n var symbolSetTimeout = __symbol__('setTimeout');\n var symbolPromise = __symbol__('Promise');\n var symbolThen = __symbol__('then');\n var _currentZoneFrame = new ZoneFrame(null, new Zone(null, null));\n var _currentTask = null;\n var _microTaskQueue = [];\n var _isDrainingMicrotaskQueue = false;\n var _uncaughtPromiseErrors = [];\n var _numberOfNestedTaskFrames = 0;\n function scheduleQueueDrain() {\n // if we are not running in any task, and there has not been anything scheduled\n // we must bootstrap the initial task creation by manually scheduling the drain\n if (_numberOfNestedTaskFrames === 0 && _microTaskQueue.length === 0) {\n // We are not running in Task, so we need to kickstart the microtask queue.\n if (global[symbolPromise]) {\n global[symbolPromise].resolve(0)[symbolThen](drainMicroTaskQueue);\n }\n else {\n global[symbolSetTimeout](drainMicroTaskQueue, 0);\n }\n }\n }\n function scheduleMicroTask(task) {\n scheduleQueueDrain();\n _microTaskQueue.push(task);\n }\n function consoleError(e) {\n if (Zone[__symbol__('ignoreConsoleErrorUncaughtError')]) {\n return;\n }\n var rejection = e && e.rejection;\n if (rejection) {\n console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined);\n }\n console.error(e);\n }\n function handleUnhandledRejection(e) {\n consoleError(e);\n try {\n var handler = Zone[__symbol__('unhandledPromiseRejectionHandler')];\n if (handler && typeof handler === 'function') {\n handler.apply(this, [e]);\n }\n }\n catch (err) {\n }\n }\n function drainMicroTaskQueue() {\n if (!_isDrainingMicrotaskQueue) {\n _isDrainingMicrotaskQueue = true;\n while (_microTaskQueue.length) {\n var queue = _microTaskQueue;\n _microTaskQueue = [];\n for (var i = 0; i < queue.length; i++) {\n var task = queue[i];\n try {\n task.zone.runTask(task, null, null);\n }\n catch (error) {\n consoleError(error);\n }\n }\n }\n while (_uncaughtPromiseErrors.length) {\n var _loop_1 = function () {\n var uncaughtPromiseError = _uncaughtPromiseErrors.shift();\n try {\n uncaughtPromiseError.zone.runGuarded(function () {\n throw uncaughtPromiseError;\n });\n }\n catch (error) {\n handleUnhandledRejection(error);\n }\n };\n while (_uncaughtPromiseErrors.length) {\n _loop_1();\n }\n }\n _isDrainingMicrotaskQueue = false;\n }\n }\n function isThenable(value) {\n return value && value.then;\n }\n function forwardResolution(value) {\n return value;\n }\n function forwardRejection(rejection) {\n return ZoneAwarePromise.reject(rejection);\n }\n var symbolState = __symbol__('state');\n var symbolValue = __symbol__('value');\n var source = 'Promise.then';\n var UNRESOLVED = null;\n var RESOLVED = true;\n var REJECTED = false;\n var REJECTED_NO_CATCH = 0;\n function makeResolver(promise, state) {\n return function (v) {\n try {\n resolvePromise(promise, state, v);\n }\n catch (err) {\n resolvePromise(promise, false, err);\n }\n // Do not return value or you will break the Promise spec.\n };\n }\n var once = function () {\n var wasCalled = false;\n return function wrapper(wrappedFunction) {\n return function () {\n if (wasCalled) {\n return;\n }\n wasCalled = true;\n wrappedFunction.apply(null, arguments);\n };\n };\n };\n // Promise Resolution\n function resolvePromise(promise, state, value) {\n var onceWrapper = once();\n if (promise === value) {\n throw new TypeError('Promise resolved with itself');\n }\n if (promise[symbolState] === UNRESOLVED) {\n // should only get value.then once based on promise spec.\n var then = null;\n try {\n if (typeof value === 'object' || typeof value === 'function') {\n then = value && value.then;\n }\n }\n catch (err) {\n onceWrapper(function () {\n resolvePromise(promise, false, err);\n })();\n return promise;\n }\n // if (value instanceof ZoneAwarePromise) {\n if (state !== REJECTED && value instanceof ZoneAwarePromise &&\n value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) &&\n value[symbolState] !== UNRESOLVED) {\n clearRejectedNoCatch(value);\n resolvePromise(promise, value[symbolState], value[symbolValue]);\n }\n else if (state !== REJECTED && typeof then === 'function') {\n try {\n then.apply(value, [\n onceWrapper(makeResolver(promise, state)), onceWrapper(makeResolver(promise, false))\n ]);\n }\n catch (err) {\n onceWrapper(function () {\n resolvePromise(promise, false, err);\n })();\n }\n }\n else {\n promise[symbolState] = state;\n var queue = promise[symbolValue];\n promise[symbolValue] = value;\n // record task information in value when error occurs, so we can\n // do some additional work such as render longStackTrace\n if (state === REJECTED && value instanceof Error) {\n value[__symbol__('currentTask')] = Zone.currentTask;\n }\n for (var i = 0; i < queue.length;) {\n scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]);\n }\n if (queue.length == 0 && state == REJECTED) {\n promise[symbolState] = REJECTED_NO_CATCH;\n try {\n throw new Error('Uncaught (in promise): ' + value +\n (value && value.stack ? '\\n' + value.stack : ''));\n }\n catch (err) {\n var error_1 = err;\n error_1.rejection = value;\n error_1.promise = promise;\n error_1.zone = Zone.current;\n error_1.task = Zone.currentTask;\n _uncaughtPromiseErrors.push(error_1);\n scheduleQueueDrain();\n }\n }\n }\n }\n // Resolving an already resolved promise is a noop.\n return promise;\n }\n function clearRejectedNoCatch(promise) {\n if (promise[symbolState] === REJECTED_NO_CATCH) {\n // if the promise is rejected no catch status\n // and queue.length > 0, means there is a error handler\n // here to handle the rejected promise, we should trigger\n // windows.rejectionhandled eventHandler or nodejs rejectionHandled\n // eventHandler\n try {\n var handler = Zone[__symbol__('rejectionHandledHandler')];\n if (handler && typeof handler === 'function') {\n handler.apply(this, [{ rejection: promise[symbolValue], promise: promise }]);\n }\n }\n catch (err) {\n }\n promise[symbolState] = REJECTED;\n for (var i = 0; i < _uncaughtPromiseErrors.length; i++) {\n if (promise === _uncaughtPromiseErrors[i].promise) {\n _uncaughtPromiseErrors.splice(i, 1);\n }\n }\n }\n }\n function scheduleResolveOrReject(promise, zone, chainPromise, onFulfilled, onRejected) {\n clearRejectedNoCatch(promise);\n var delegate = promise[symbolState] ?\n (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution :\n (typeof onRejected === 'function') ? onRejected : forwardRejection;\n zone.scheduleMicroTask(source, function () {\n try {\n resolvePromise(chainPromise, true, zone.run(delegate, undefined, [promise[symbolValue]]));\n }\n catch (error) {\n resolvePromise(chainPromise, false, error);\n }\n });\n }\n var ZoneAwarePromise = (function () {\n function ZoneAwarePromise(executor) {\n var promise = this;\n if (!(promise instanceof ZoneAwarePromise)) {\n throw new Error('Must be an instanceof Promise.');\n }\n promise[symbolState] = UNRESOLVED;\n promise[symbolValue] = []; // queue;\n try {\n executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED));\n }\n catch (error) {\n resolvePromise(promise, false, error);\n }\n }\n ZoneAwarePromise.toString = function () {\n return 'function ZoneAwarePromise() { [native code] }';\n };\n ZoneAwarePromise.resolve = function (value) {\n return resolvePromise(new this(null), RESOLVED, value);\n };\n ZoneAwarePromise.reject = function (error) {\n return resolvePromise(new this(null), REJECTED, error);\n };\n ZoneAwarePromise.race = function (values) {\n var resolve;\n var reject;\n var promise = new this(function (res, rej) {\n _a = [res, rej], resolve = _a[0], reject = _a[1];\n var _a;\n });\n function onResolve(value) {\n promise && (promise = null || resolve(value));\n }\n function onReject(error) {\n promise && (promise = null || reject(error));\n }\n for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {\n var value = values_1[_i];\n if (!isThenable(value)) {\n value = this.resolve(value);\n }\n value.then(onResolve, onReject);\n }\n return promise;\n };\n ZoneAwarePromise.all = function (values) {\n var resolve;\n var reject;\n var promise = new this(function (res, rej) {\n resolve = res;\n reject = rej;\n });\n var count = 0;\n var resolvedValues = [];\n for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {\n var value = values_2[_i];\n if (!isThenable(value)) {\n value = this.resolve(value);\n }\n value.then((function (index) { return function (value) {\n resolvedValues[index] = value;\n count--;\n if (!count) {\n resolve(resolvedValues);\n }\n }; })(count), reject);\n count++;\n }\n if (!count)\n resolve(resolvedValues);\n return promise;\n };\n ZoneAwarePromise.prototype.then = function (onFulfilled, onRejected) {\n var chainPromise = new this.constructor(null);\n var zone = Zone.current;\n if (this[symbolState] == UNRESOLVED) {\n this[symbolValue].push(zone, chainPromise, onFulfilled, onRejected);\n }\n else {\n scheduleResolveOrReject(this, zone, chainPromise, onFulfilled, onRejected);\n }\n return chainPromise;\n };\n ZoneAwarePromise.prototype.catch = function (onRejected) {\n return this.then(null, onRejected);\n };\n return ZoneAwarePromise;\n }());\n // Protect against aggressive optimizers dropping seemingly unused properties.\n // E.g. Closure Compiler in advanced mode.\n ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve;\n ZoneAwarePromise['reject'] = ZoneAwarePromise.reject;\n ZoneAwarePromise['race'] = ZoneAwarePromise.race;\n ZoneAwarePromise['all'] = ZoneAwarePromise.all;\n var NativePromise = global[symbolPromise] = global['Promise'];\n global['Promise'] = ZoneAwarePromise;\n var symbolThenPatched = __symbol__('thenPatched');\n function patchThen(Ctor) {\n var proto = Ctor.prototype;\n var originalThen = proto.then;\n // Keep a reference to the original method.\n proto[symbolThen] = originalThen;\n Ctor.prototype.then = function (onResolve, onReject) {\n var _this = this;\n var wrapped = new ZoneAwarePromise(function (resolve, reject) {\n originalThen.call(_this, resolve, reject);\n });\n return wrapped.then(onResolve, onReject);\n };\n Ctor[symbolThenPatched] = true;\n }\n function zoneify(fn) {\n return function () {\n var resultPromise = fn.apply(this, arguments);\n if (resultPromise instanceof ZoneAwarePromise) {\n return resultPromise;\n }\n var Ctor = resultPromise.constructor;\n if (!Ctor[symbolThenPatched]) {\n patchThen(Ctor);\n }\n return resultPromise;\n };\n }\n if (NativePromise) {\n patchThen(NativePromise);\n var fetch_1 = global['fetch'];\n if (typeof fetch_1 == 'function') {\n global['fetch'] = zoneify(fetch_1);\n }\n }\n // This is not part of public API, but it is usefull for tests, so we expose it.\n Promise[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors;\n var blacklistedStackFramesSymbol = Zone.__symbol__('blacklistedStackFrames');\n var NativeError = global[__symbol__('Error')] = global.Error;\n // Store the frames which should be removed from the stack frames\n var blackListedStackFrames = {};\n // We must find the frame where Error was created, otherwise we assume we don't understand stack\n var zoneAwareFrame1;\n var zoneAwareFrame2;\n global.Error = ZoneAwareError;\n var stackRewrite = 'stackRewrite';\n /**\n * This is ZoneAwareError which processes the stack frame and cleans up extra frames as well as\n * adds zone information to it.\n */\n function ZoneAwareError() {\n var _this = this;\n // We always have to return native error otherwise the browser console will not work.\n var error = NativeError.apply(this, arguments);\n if (!error.stack) {\n // in IE, the error.stack will be undefined\n // when error was constructed, it will only\n // be available when throw\n try {\n throw error;\n }\n catch (err) {\n error = err;\n }\n }\n // Save original stack trace\n var originalStack = error['originalStack'] = error.stack;\n // Process the stack trace and rewrite the frames.\n if (ZoneAwareError[stackRewrite] && originalStack) {\n var frames_1 = originalStack.split('\\n');\n var zoneFrame = _currentZoneFrame;\n var i = 0;\n // Find the first frame\n while (!(frames_1[i] === zoneAwareFrame1 || frames_1[i] === zoneAwareFrame2) &&\n i < frames_1.length) {\n i++;\n }\n for (; i < frames_1.length && zoneFrame; i++) {\n var frame = frames_1[i];\n if (frame.trim()) {\n switch (blackListedStackFrames[frame]) {\n case 0 /* blackList */:\n frames_1.splice(i, 1);\n i--;\n break;\n case 1 /* transition */:\n if (zoneFrame.parent) {\n // This is the special frame where zone changed. Print and process it accordingly\n frames_1[i] += \" [\" + zoneFrame.parent.zone.name + \" => \" + zoneFrame.zone.name + \"]\";\n zoneFrame = zoneFrame.parent;\n }\n else {\n zoneFrame = null;\n }\n break;\n default:\n frames_1[i] += \" [\" + zoneFrame.zone.name + \"]\";\n }\n }\n }\n try {\n error.stack = error.zoneAwareStack = frames_1.join('\\n');\n }\n catch (e) {\n // ignore as some browsers don't allow overriding of stack\n }\n }\n if (this instanceof NativeError && this.constructor != NativeError) {\n // We got called with a `new` operator AND we are subclass of ZoneAwareError\n // in that case we have to copy all of our properties to `this`.\n Object.keys(error).concat('stack', 'message').forEach(function (key) {\n if (error[key] !== undefined) {\n try {\n _this[key] = error[key];\n }\n catch (e) {\n // ignore the assignment in case it is a setter and it throws.\n }\n }\n });\n return this;\n }\n return error;\n }\n // Copy the prototype so that instanceof operator works as expected\n ZoneAwareError.prototype = NativeError.prototype;\n ZoneAwareError[blacklistedStackFramesSymbol] = blackListedStackFrames;\n ZoneAwareError[stackRewrite] = false;\n // those properties need special handling\n var specialPropertyNames = ['stackTraceLimit', 'captureStackTrace', 'prepareStackTrace'];\n // those properties of NativeError should be set to ZoneAwareError\n var nativeErrorProperties = Object.keys(NativeError);\n if (nativeErrorProperties) {\n nativeErrorProperties.forEach(function (prop) {\n if (specialPropertyNames.filter(function (sp) { return sp === prop; }).length === 0) {\n Object.defineProperty(ZoneAwareError, prop, {\n get: function () {\n return NativeError[prop];\n },\n set: function (value) {\n NativeError[prop] = value;\n }\n });\n }\n });\n }\n if (NativeError.hasOwnProperty('stackTraceLimit')) {\n // Extend default stack limit as we will be removing few frames.\n NativeError.stackTraceLimit = Math.max(NativeError.stackTraceLimit, 15);\n // make sure that ZoneAwareError has the same property which forwards to NativeError.\n Object.defineProperty(ZoneAwareError, 'stackTraceLimit', {\n get: function () {\n return NativeError.stackTraceLimit;\n },\n set: function (value) {\n return NativeError.stackTraceLimit = value;\n }\n });\n }\n if (NativeError.hasOwnProperty('captureStackTrace')) {\n Object.defineProperty(ZoneAwareError, 'captureStackTrace', {\n // add named function here because we need to remove this\n // stack frame when prepareStackTrace below\n value: function zoneCaptureStackTrace(targetObject, constructorOpt) {\n NativeError.captureStackTrace(targetObject, constructorOpt);\n }\n });\n }\n Object.defineProperty(ZoneAwareError, 'prepareStackTrace', {\n get: function () {\n return NativeError.prepareStackTrace;\n },\n set: function (value) {\n if (!value || typeof value !== 'function') {\n return NativeError.prepareStackTrace = value;\n }\n return NativeError.prepareStackTrace = function (error, structuredStackTrace) {\n // remove additional stack information from ZoneAwareError.captureStackTrace\n if (structuredStackTrace) {\n for (var i = 0; i < structuredStackTrace.length; i++) {\n var st = structuredStackTrace[i];\n // remove the first function which name is zoneCaptureStackTrace\n if (st.getFunctionName() === 'zoneCaptureStackTrace') {\n structuredStackTrace.splice(i, 1);\n break;\n }\n }\n }\n return value.apply(this, [error, structuredStackTrace]);\n };\n }\n });\n // Now we need to populate the `blacklistedStackFrames` as well as find the\n // run/runGuraded/runTask frames. This is done by creating a detect zone and then threading\n // the execution through all of the above methods so that we can look at the stack trace and\n // find the frames of interest.\n var detectZone = Zone.current.fork({\n name: 'detect',\n onInvoke: function (parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {\n // Here only so that it will show up in the stack frame so that it can be black listed.\n return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);\n },\n onHandleError: function (parentZD, current, target, error) {\n if (error.originalStack && Error === ZoneAwareError) {\n var frames_2 = error.originalStack.split(/\\n/);\n var runFrame = false, runGuardedFrame = false, runTaskFrame = false;\n while (frames_2.length) {\n var frame = frames_2.shift();\n // On safari it is possible to have stack frame with no line number.\n // This check makes sure that we don't filter frames on name only (must have\n // linenumber)\n if (/:\\d+:\\d+/.test(frame)) {\n // Get rid of the path so that we don't accidentally find function name in path.\n // In chrome the separator is `(` and `@` in FF and safari\n // Chrome: at Zone.run (zone.js:100)\n // Chrome: at Zone.run (http://localhost:9876/base/build/lib/zone.js:100:24)\n // FireFox: Zone.prototype.run@http://localhost:9876/base/build/lib/zone.js:101:24\n // Safari: run@http://localhost:9876/base/build/lib/zone.js:101:24\n var fnName = frame.split('(')[0].split('@')[0];\n var frameType = 1;\n if (fnName.indexOf('ZoneAwareError') !== -1) {\n zoneAwareFrame1 = frame;\n zoneAwareFrame2 = frame.replace('Error.', '');\n blackListedStackFrames[zoneAwareFrame2] = 0 /* blackList */;\n }\n if (fnName.indexOf('runGuarded') !== -1) {\n runGuardedFrame = true;\n }\n else if (fnName.indexOf('runTask') !== -1) {\n runTaskFrame = true;\n }\n else if (fnName.indexOf('run') !== -1) {\n runFrame = true;\n }\n else {\n frameType = 0 /* blackList */;\n }\n blackListedStackFrames[frame] = frameType;\n // Once we find all of the frames we can stop looking.\n if (runFrame && runGuardedFrame && runTaskFrame) {\n ZoneAwareError[stackRewrite] = true;\n break;\n }\n }\n }\n }\n return false;\n }\n });\n // carefully constructor a stack frame which contains all of the frames of interest which\n // need to be detected and blacklisted.\n // carefully constructor a stack frame which contains all of the frames of interest which\n // need to be detected and blacklisted.\n var detectRunFn = function () {\n detectZone.run(function () {\n detectZone.runGuarded(function () {\n throw new ZoneAwareError(ZoneAwareError, NativeError);\n });\n });\n };\n // Cause the error to extract the stack frames.\n detectZone.runTask(detectZone.scheduleMacroTask('detect', detectRunFn, null, function () { return null; }, null));\n return global['Zone'] = Zone;\n})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * Suppress closure compiler errors about unknown 'Zone' variable\n * @fileoverview\n * @suppress {undefinedVars,globalThis}\n */\nvar zoneSymbol = function (n) { return \"__zone_symbol__\" + n; };\nvar _global$1 = typeof window === 'object' && window || typeof self === 'object' && self || global;\nfunction bindArguments(args, source) {\n for (var i = args.length - 1; i >= 0; i--) {\n if (typeof args[i] === 'function') {\n args[i] = Zone.current.wrap(args[i], source + '_' + i);\n }\n }\n return args;\n}\nfunction patchPrototype(prototype, fnNames) {\n var source = prototype.constructor['name'];\n var _loop_1 = function (i) {\n var name_1 = fnNames[i];\n var delegate = prototype[name_1];\n if (delegate) {\n prototype[name_1] = (function (delegate) {\n return function () {\n return delegate.apply(this, bindArguments(arguments, source + '.' + name_1));\n };\n })(delegate);\n }\n };\n for (var i = 0; i < fnNames.length; i++) {\n _loop_1(i);\n }\n}\nvar isWebWorker = (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope);\nvar isNode = (!('nw' in _global$1) && typeof process !== 'undefined' &&\n {}.toString.call(process) === '[object process]');\nvar isBrowser = !isNode && !isWebWorker && !!(typeof window !== 'undefined' && window['HTMLElement']);\n// we are in electron of nw, so we are both browser and nodejs\nvar isMix = typeof process !== 'undefined' &&\n {}.toString.call(process) === '[object process]' && !isWebWorker &&\n !!(typeof window !== 'undefined' && window['HTMLElement']);\nfunction patchProperty(obj, prop) {\n var desc = Object.getOwnPropertyDescriptor(obj, prop) || { enumerable: true, configurable: true };\n var originalDesc = Object.getOwnPropertyDescriptor(obj, 'original' + prop);\n if (!originalDesc && desc.get) {\n Object.defineProperty(obj, 'original' + prop, { enumerable: false, configurable: true, get: desc.get });\n }\n // A property descriptor cannot have getter/setter and be writable\n // deleting the writable and value properties avoids this error:\n //\n // TypeError: property descriptors must not specify a value or be writable when a\n // getter or setter has been specified\n delete desc.writable;\n delete desc.value;\n // substr(2) cuz 'onclick' -> 'click', etc\n var eventName = prop.substr(2);\n var _prop = zoneSymbol('_' + prop);\n desc.set = function (fn) {\n if (this[_prop]) {\n this.removeEventListener(eventName, this[_prop]);\n }\n if (typeof fn === 'function') {\n var wrapFn = function (event) {\n var result;\n result = fn.apply(this, arguments);\n if (result != undefined && !result) {\n event.preventDefault();\n }\n return result;\n };\n this[_prop] = wrapFn;\n this.addEventListener(eventName, wrapFn, false);\n }\n else {\n this[_prop] = null;\n }\n };\n // The getter would return undefined for unassigned properties but the default value of an\n // unassigned property is null\n desc.get = function () {\n var r = this[_prop] || null;\n // result will be null when use inline event attribute,\n // such as \n // because the onclick function is internal raw uncompiled handler\n // the onclick will be evaluated when first time event was triggered or\n // the property is accessed, https://github.com/angular/zone.js/issues/525\n // so we should use original native get to retrieve the handler\n if (r === null) {\n if (originalDesc && originalDesc.get) {\n r = originalDesc.get.apply(this, arguments);\n if (r) {\n desc.set.apply(this, [r]);\n if (typeof this['removeAttribute'] === 'function') {\n this.removeAttribute(prop);\n }\n }\n }\n }\n return this[_prop] || null;\n };\n Object.defineProperty(obj, prop, desc);\n}\n\nfunction patchOnProperties(obj, properties) {\n var onProperties = [];\n for (var prop in obj) {\n if (prop.substr(0, 2) == 'on') {\n onProperties.push(prop);\n }\n }\n for (var j = 0; j < onProperties.length; j++) {\n patchProperty(obj, onProperties[j]);\n }\n if (properties) {\n for (var i = 0; i < properties.length; i++) {\n patchProperty(obj, 'on' + properties[i]);\n }\n }\n}\n\nvar EVENT_TASKS = zoneSymbol('eventTasks');\n// For EventTarget\nvar ADD_EVENT_LISTENER = 'addEventListener';\nvar REMOVE_EVENT_LISTENER = 'removeEventListener';\nfunction findExistingRegisteredTask(target, handler, name, capture, remove) {\n var eventTasks = target[EVENT_TASKS];\n if (eventTasks) {\n for (var i = 0; i < eventTasks.length; i++) {\n var eventTask = eventTasks[i];\n var data = eventTask.data;\n var listener = data.handler;\n if ((data.handler === handler || listener.listener === handler) &&\n data.useCapturing === capture && data.eventName === name) {\n if (remove) {\n eventTasks.splice(i, 1);\n }\n return eventTask;\n }\n }\n }\n return null;\n}\nfunction attachRegisteredEvent(target, eventTask, isPrepend) {\n var eventTasks = target[EVENT_TASKS];\n if (!eventTasks) {\n eventTasks = target[EVENT_TASKS] = [];\n }\n if (isPrepend) {\n eventTasks.unshift(eventTask);\n }\n else {\n eventTasks.push(eventTask);\n }\n}\nvar defaultListenerMetaCreator = function (self, args) {\n return {\n useCapturing: args[2],\n eventName: args[0],\n handler: args[1],\n target: self || _global$1,\n name: args[0],\n invokeAddFunc: function (addFnSymbol, delegate) {\n if (delegate && delegate.invoke) {\n return this.target[addFnSymbol](this.eventName, delegate.invoke, this.useCapturing);\n }\n else {\n return this.target[addFnSymbol](this.eventName, delegate, this.useCapturing);\n }\n },\n invokeRemoveFunc: function (removeFnSymbol, delegate) {\n if (delegate && delegate.invoke) {\n return this.target[removeFnSymbol](this.eventName, delegate.invoke, this.useCapturing);\n }\n else {\n return this.target[removeFnSymbol](this.eventName, delegate, this.useCapturing);\n }\n }\n };\n};\nfunction makeZoneAwareAddListener(addFnName, removeFnName, useCapturingParam, allowDuplicates, isPrepend, metaCreator) {\n if (useCapturingParam === void 0) { useCapturingParam = true; }\n if (allowDuplicates === void 0) { allowDuplicates = false; }\n if (isPrepend === void 0) { isPrepend = false; }\n if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }\n var addFnSymbol = zoneSymbol(addFnName);\n var removeFnSymbol = zoneSymbol(removeFnName);\n var defaultUseCapturing = useCapturingParam ? false : undefined;\n function scheduleEventListener(eventTask) {\n var meta = eventTask.data;\n attachRegisteredEvent(meta.target, eventTask, isPrepend);\n return meta.invokeAddFunc(addFnSymbol, eventTask);\n }\n function cancelEventListener(eventTask) {\n var meta = eventTask.data;\n findExistingRegisteredTask(meta.target, eventTask.invoke, meta.eventName, meta.useCapturing, true);\n return meta.invokeRemoveFunc(removeFnSymbol, eventTask);\n }\n return function zoneAwareAddListener(self, args) {\n var data = metaCreator(self, args);\n data.useCapturing = data.useCapturing || defaultUseCapturing;\n // - Inside a Web Worker, `this` is undefined, the context is `global`\n // - When `addEventListener` is called on the global context in strict mode, `this` is undefined\n // see https://github.com/angular/zone.js/issues/190\n var delegate = null;\n if (typeof data.handler == 'function') {\n delegate = data.handler;\n }\n else if (data.handler && data.handler.handleEvent) {\n delegate = function (event) { return data.handler.handleEvent(event); };\n }\n var validZoneHandler = false;\n try {\n // In cross site contexts (such as WebDriver frameworks like Selenium),\n // accessing the handler object here will cause an exception to be thrown which\n // will fail tests prematurely.\n validZoneHandler = data.handler && data.handler.toString() === '[object FunctionWrapper]';\n }\n catch (error) {\n // Returning nothing here is fine, because objects in a cross-site context are unusable\n return;\n }\n // Ignore special listeners of IE11 & Edge dev tools, see\n // https://github.com/angular/zone.js/issues/150\n if (!delegate || validZoneHandler) {\n return data.invokeAddFunc(addFnSymbol, data.handler);\n }\n if (!allowDuplicates) {\n var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.useCapturing, false);\n if (eventTask) {\n // we already registered, so this will have noop.\n return data.invokeAddFunc(addFnSymbol, eventTask);\n }\n }\n var zone = Zone.current;\n var source = data.target.constructor['name'] + '.' + addFnName + ':' + data.eventName;\n zone.scheduleEventTask(source, delegate, data, scheduleEventListener, cancelEventListener);\n };\n}\nfunction makeZoneAwareRemoveListener(fnName, useCapturingParam, metaCreator) {\n if (useCapturingParam === void 0) { useCapturingParam = true; }\n if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }\n var symbol = zoneSymbol(fnName);\n var defaultUseCapturing = useCapturingParam ? false : undefined;\n return function zoneAwareRemoveListener(self, args) {\n var data = metaCreator(self, args);\n data.useCapturing = data.useCapturing || defaultUseCapturing;\n // - Inside a Web Worker, `this` is undefined, the context is `global`\n // - When `addEventListener` is called on the global context in strict mode, `this` is undefined\n // see https://github.com/angular/zone.js/issues/190\n var eventTask = findExistingRegisteredTask(data.target, data.handler, data.eventName, data.useCapturing, true);\n if (eventTask) {\n eventTask.zone.cancelTask(eventTask);\n }\n else {\n data.invokeRemoveFunc(symbol, data.handler);\n }\n };\n}\n\n\nvar zoneAwareAddEventListener = makeZoneAwareAddListener(ADD_EVENT_LISTENER, REMOVE_EVENT_LISTENER);\nvar zoneAwareRemoveEventListener = makeZoneAwareRemoveListener(REMOVE_EVENT_LISTENER);\nfunction patchEventTargetMethods(obj, addFnName, removeFnName, metaCreator) {\n if (addFnName === void 0) { addFnName = ADD_EVENT_LISTENER; }\n if (removeFnName === void 0) { removeFnName = REMOVE_EVENT_LISTENER; }\n if (metaCreator === void 0) { metaCreator = defaultListenerMetaCreator; }\n if (obj && obj[addFnName]) {\n patchMethod(obj, addFnName, function () { return makeZoneAwareAddListener(addFnName, removeFnName, true, false, false, metaCreator); });\n patchMethod(obj, removeFnName, function () { return makeZoneAwareRemoveListener(removeFnName, true, metaCreator); });\n return true;\n }\n else {\n return false;\n }\n}\nvar originalInstanceKey = zoneSymbol('originalInstance');\n// wrap some native API on `window`\nfunction patchClass(className) {\n var OriginalClass = _global$1[className];\n if (!OriginalClass)\n return;\n _global$1[className] = function () {\n var a = bindArguments(arguments, className);\n switch (a.length) {\n case 0:\n this[originalInstanceKey] = new OriginalClass();\n break;\n case 1:\n this[originalInstanceKey] = new OriginalClass(a[0]);\n break;\n case 2:\n this[originalInstanceKey] = new OriginalClass(a[0], a[1]);\n break;\n case 3:\n this[originalInstanceKey] = new OriginalClass(a[0], a[1], a[2]);\n break;\n case 4:\n this[originalInstanceKey] = new OriginalClass(a[0], a[1], a[2], a[3]);\n break;\n default:\n throw new Error('Arg list too long.');\n }\n };\n var instance = new OriginalClass(function () { });\n var prop;\n for (prop in instance) {\n // https://bugs.webkit.org/show_bug.cgi?id=44721\n if (className === 'XMLHttpRequest' && prop === 'responseBlob')\n continue;\n (function (prop) {\n if (typeof instance[prop] === 'function') {\n _global$1[className].prototype[prop] = function () {\n return this[originalInstanceKey][prop].apply(this[originalInstanceKey], arguments);\n };\n }\n else {\n Object.defineProperty(_global$1[className].prototype, prop, {\n set: function (fn) {\n if (typeof fn === 'function') {\n this[originalInstanceKey][prop] = Zone.current.wrap(fn, className + '.' + prop);\n }\n else {\n this[originalInstanceKey][prop] = fn;\n }\n },\n get: function () {\n return this[originalInstanceKey][prop];\n }\n });\n }\n }(prop));\n }\n for (prop in OriginalClass) {\n if (prop !== 'prototype' && OriginalClass.hasOwnProperty(prop)) {\n _global$1[className][prop] = OriginalClass[prop];\n }\n }\n}\n\nfunction createNamedFn(name, delegate) {\n try {\n return (Function('f', \"return function \" + name + \"(){return f(this, arguments)}\"))(delegate);\n }\n catch (error) {\n // if we fail, we must be CSP, just return delegate.\n return function () {\n return delegate(this, arguments);\n };\n }\n}\nfunction patchMethod(target, name, patchFn) {\n var proto = target;\n while (proto && Object.getOwnPropertyNames(proto).indexOf(name) === -1) {\n proto = Object.getPrototypeOf(proto);\n }\n if (!proto && target[name]) {\n // somehow we did not find it, but we can see it. This happens on IE for Window properties.\n proto = target;\n }\n var delegateName = zoneSymbol(name);\n var delegate;\n if (proto && !(delegate = proto[delegateName])) {\n delegate = proto[delegateName] = proto[name];\n proto[name] = createNamedFn(name, patchFn(delegate, delegateName, name));\n }\n return delegate;\n}\n// TODO: @JiaLiPassion, support cancel task later if necessary\n\n\nfunction findEventTask(target, evtName) {\n var eventTasks = target[zoneSymbol('eventTasks')];\n var result = [];\n if (eventTasks) {\n for (var i = 0; i < eventTasks.length; i++) {\n var eventTask = eventTasks[i];\n var data = eventTask.data;\n var eventName = data && data.eventName;\n if (eventName === evtName) {\n result.push(eventTask);\n }\n }\n }\n return result;\n}\nZone[zoneSymbol('patchEventTargetMethods')] = patchEventTargetMethods;\nZone[zoneSymbol('patchOnProperties')] = patchOnProperties;\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction patchTimer(window, setName, cancelName, nameSuffix) {\n var setNative = null;\n var clearNative = null;\n setName += nameSuffix;\n cancelName += nameSuffix;\n var tasksByHandleId = {};\n function scheduleTask(task) {\n var data = task.data;\n function timer() {\n try {\n task.invoke.apply(this, arguments);\n }\n finally {\n delete tasksByHandleId[data.handleId];\n }\n }\n \n data.args[0] = timer;\n data.handleId = setNative.apply(window, data.args);\n tasksByHandleId[data.handleId] = task;\n return task;\n }\n function clearTask(task) {\n delete tasksByHandleId[task.data.handleId];\n return clearNative(task.data.handleId);\n }\n setNative =\n patchMethod(window, setName, function (delegate) { return function (self, args) {\n if (typeof args[0] === 'function') {\n var zone = Zone.current;\n var options = {\n handleId: null,\n isPeriodic: nameSuffix === 'Interval',\n delay: (nameSuffix === 'Timeout' || nameSuffix === 'Interval') ? args[1] || 0 : null,\n args: args\n };\n var task = zone.scheduleMacroTask(setName, args[0], options, scheduleTask, clearTask);\n if (!task) {\n return task;\n }\n // Node.js must additionally support the ref and unref functions.\n var handle = task.data.handleId;\n // check whether handle is null, because some polyfill or browser\n // may return undefined from setTimeout/setInterval/setImmediate/requestAnimationFrame\n if (handle && handle.ref && handle.unref && typeof handle.ref === 'function' &&\n typeof handle.unref === 'function') {\n task.ref = handle.ref.bind(handle);\n task.unref = handle.unref.bind(handle);\n }\n return task;\n }\n else {\n // cause an error by calling it directly.\n return delegate.apply(window, args);\n }\n }; });\n clearNative =\n patchMethod(window, cancelName, function (delegate) { return function (self, args) {\n var task = typeof args[0] === 'number' ? tasksByHandleId[args[0]] : args[0];\n if (task && typeof task.type === 'string') {\n if (task.state !== 'notScheduled' &&\n (task.cancelFn && task.data.isPeriodic || task.runCount === 0)) {\n // Do not cancel already canceled functions\n task.zone.cancelTask(task);\n }\n }\n else {\n // cause an error by calling it directly.\n delegate.apply(window, args);\n }\n }; });\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/*\n * This is necessary for Chrome and Chrome mobile, to enable\n * things like redefining `createdCallback` on an element.\n */\nvar _defineProperty = Object[zoneSymbol('defineProperty')] = Object.defineProperty;\nvar _getOwnPropertyDescriptor = Object[zoneSymbol('getOwnPropertyDescriptor')] =\n Object.getOwnPropertyDescriptor;\nvar _create = Object.create;\nvar unconfigurablesKey = zoneSymbol('unconfigurables');\nfunction propertyPatch() {\n Object.defineProperty = function (obj, prop, desc) {\n if (isUnconfigurable(obj, prop)) {\n throw new TypeError('Cannot assign to read only property \\'' + prop + '\\' of ' + obj);\n }\n var originalConfigurableFlag = desc.configurable;\n if (prop !== 'prototype') {\n desc = rewriteDescriptor(obj, prop, desc);\n }\n return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag);\n };\n Object.defineProperties = function (obj, props) {\n Object.keys(props).forEach(function (prop) {\n Object.defineProperty(obj, prop, props[prop]);\n });\n return obj;\n };\n Object.create = function (obj, proto) {\n if (typeof proto === 'object' && !Object.isFrozen(proto)) {\n Object.keys(proto).forEach(function (prop) {\n proto[prop] = rewriteDescriptor(obj, prop, proto[prop]);\n });\n }\n return _create(obj, proto);\n };\n Object.getOwnPropertyDescriptor = function (obj, prop) {\n var desc = _getOwnPropertyDescriptor(obj, prop);\n if (isUnconfigurable(obj, prop)) {\n desc.configurable = false;\n }\n return desc;\n };\n}\n\nfunction _redefineProperty(obj, prop, desc) {\n var originalConfigurableFlag = desc.configurable;\n desc = rewriteDescriptor(obj, prop, desc);\n return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag);\n}\n\nfunction isUnconfigurable(obj, prop) {\n return obj && obj[unconfigurablesKey] && obj[unconfigurablesKey][prop];\n}\nfunction rewriteDescriptor(obj, prop, desc) {\n desc.configurable = true;\n if (!desc.configurable) {\n if (!obj[unconfigurablesKey]) {\n _defineProperty(obj, unconfigurablesKey, { writable: true, value: {} });\n }\n obj[unconfigurablesKey][prop] = true;\n }\n return desc;\n}\nfunction _tryDefineProperty(obj, prop, desc, originalConfigurableFlag) {\n try {\n return _defineProperty(obj, prop, desc);\n }\n catch (error) {\n if (desc.configurable) {\n // In case of errors, when the configurable flag was likely set by rewriteDescriptor(), let's\n // retry with the original flag value\n if (typeof originalConfigurableFlag == 'undefined') {\n delete desc.configurable;\n }\n else {\n desc.configurable = originalConfigurableFlag;\n }\n try {\n return _defineProperty(obj, prop, desc);\n }\n catch (error) {\n var descJson = null;\n try {\n descJson = JSON.stringify(desc);\n }\n catch (error) {\n descJson = descJson.toString();\n }\n console.log(\"Attempting to configure '\" + prop + \"' with descriptor '\" + descJson + \"' on object '\" + obj + \"' and got error, giving up: \" + error);\n }\n }\n else {\n throw error;\n }\n }\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nvar WTF_ISSUE_555 = 'Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video';\nvar NO_EVENT_TARGET = 'ApplicationCache,EventSource,FileReader,InputMethodContext,MediaController,MessagePort,Node,Performance,SVGElementInstance,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebKitNamedFlow,Window,Worker,WorkerGlobalScope,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload,IDBRequest,IDBOpenDBRequest,IDBDatabase,IDBTransaction,IDBCursor,DBIndex,WebSocket'\n .split(',');\nvar EVENT_TARGET = 'EventTarget';\nfunction eventTargetPatch(_global) {\n var apis = [];\n var isWtf = _global['wtf'];\n if (isWtf) {\n // Workaround for: https://github.com/google/tracing-framework/issues/555\n apis = WTF_ISSUE_555.split(',').map(function (v) { return 'HTML' + v + 'Element'; }).concat(NO_EVENT_TARGET);\n }\n else if (_global[EVENT_TARGET]) {\n apis.push(EVENT_TARGET);\n }\n else {\n // Note: EventTarget is not available in all browsers,\n // if it's not available, we instead patch the APIs in the IDL that inherit from EventTarget\n apis = NO_EVENT_TARGET;\n }\n for (var i = 0; i < apis.length; i++) {\n var type = _global[apis[i]];\n patchEventTargetMethods(type && type.prototype);\n }\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// we have to patch the instance since the proto is non-configurable\nfunction apply(_global) {\n var WS = _global.WebSocket;\n // On Safari window.EventTarget doesn't exist so need to patch WS add/removeEventListener\n // On older Chrome, no need since EventTarget was already patched\n if (!_global.EventTarget) {\n patchEventTargetMethods(WS.prototype);\n }\n _global.WebSocket = function (a, b) {\n var socket = arguments.length > 1 ? new WS(a, b) : new WS(a);\n var proxySocket;\n // Safari 7.0 has non-configurable own 'onmessage' and friends properties on the socket instance\n var onmessageDesc = Object.getOwnPropertyDescriptor(socket, 'onmessage');\n if (onmessageDesc && onmessageDesc.configurable === false) {\n proxySocket = Object.create(socket);\n ['addEventListener', 'removeEventListener', 'send', 'close'].forEach(function (propName) {\n proxySocket[propName] = function () {\n return socket[propName].apply(socket, arguments);\n };\n });\n }\n else {\n // we can patch the real socket\n proxySocket = socket;\n }\n patchOnProperties(proxySocket, ['close', 'error', 'message', 'open']);\n return proxySocket;\n };\n for (var prop in WS) {\n _global.WebSocket[prop] = WS[prop];\n }\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nvar eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror'\n .split(' ');\nfunction propertyDescriptorPatch(_global) {\n if (isNode && !isMix) {\n return;\n }\n var supportsWebSocket = typeof WebSocket !== 'undefined';\n if (canPatchViaPropertyDescriptor()) {\n // for browsers that we can patch the descriptor: Chrome & Firefox\n if (isBrowser) {\n patchOnProperties(window, eventNames);\n patchOnProperties(Document.prototype, eventNames);\n if (typeof SVGElement !== 'undefined') {\n patchOnProperties(SVGElement.prototype, eventNames);\n }\n patchOnProperties(HTMLElement.prototype, eventNames);\n }\n patchOnProperties(XMLHttpRequest.prototype, null);\n if (typeof IDBIndex !== 'undefined') {\n patchOnProperties(IDBIndex.prototype, null);\n patchOnProperties(IDBRequest.prototype, null);\n patchOnProperties(IDBOpenDBRequest.prototype, null);\n patchOnProperties(IDBDatabase.prototype, null);\n patchOnProperties(IDBTransaction.prototype, null);\n patchOnProperties(IDBCursor.prototype, null);\n }\n if (supportsWebSocket) {\n patchOnProperties(WebSocket.prototype, null);\n }\n }\n else {\n // Safari, Android browsers (Jelly Bean)\n patchViaCapturingAllTheEvents();\n patchClass('XMLHttpRequest');\n if (supportsWebSocket) {\n apply(_global);\n }\n }\n}\nfunction canPatchViaPropertyDescriptor() {\n if ((isBrowser || isMix) && !Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') &&\n typeof Element !== 'undefined') {\n // WebKit https://bugs.webkit.org/show_bug.cgi?id=134364\n // IDL interface attributes are not configurable\n var desc = Object.getOwnPropertyDescriptor(Element.prototype, 'onclick');\n if (desc && !desc.configurable)\n return false;\n }\n var xhrDesc = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'onreadystatechange');\n // add enumerable and configurable here because in opera\n // by default XMLHttpRequest.prototype.onreadystatechange is undefined\n // without adding enumerable and configurable will cause onreadystatechange\n // non-configurable\n Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', {\n enumerable: true,\n configurable: true,\n get: function () {\n return true;\n }\n });\n var req = new XMLHttpRequest();\n var result = !!req.onreadystatechange;\n // restore original desc\n Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', xhrDesc || {});\n return result;\n}\n\nvar unboundKey = zoneSymbol('unbound');\n// Whenever any eventListener fires, we check the eventListener target and all parents\n// for `onwhatever` properties and replace them with zone-bound functions\n// - Chrome (for now)\nfunction patchViaCapturingAllTheEvents() {\n var _loop_1 = function (i) {\n var property = eventNames[i];\n var onproperty = 'on' + property;\n self.addEventListener(property, function (event) {\n var elt = event.target, bound, source;\n if (elt) {\n source = elt.constructor['name'] + '.' + onproperty;\n }\n else {\n source = 'unknown.' + onproperty;\n }\n while (elt) {\n if (elt[onproperty] && !elt[onproperty][unboundKey]) {\n bound = Zone.current.wrap(elt[onproperty], source);\n bound[unboundKey] = elt[onproperty];\n elt[onproperty] = bound;\n }\n elt = elt.parentElement;\n }\n }, true);\n };\n for (var i = 0; i < eventNames.length; i++) {\n _loop_1(i);\n }\n \n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nfunction registerElementPatch(_global) {\n if ((!isBrowser && !isMix) || !('registerElement' in _global.document)) {\n return;\n }\n var _registerElement = document.registerElement;\n var callbacks = ['createdCallback', 'attachedCallback', 'detachedCallback', 'attributeChangedCallback'];\n document.registerElement = function (name, opts) {\n if (opts && opts.prototype) {\n callbacks.forEach(function (callback) {\n var source = 'Document.registerElement::' + callback;\n if (opts.prototype.hasOwnProperty(callback)) {\n var descriptor = Object.getOwnPropertyDescriptor(opts.prototype, callback);\n if (descriptor && descriptor.value) {\n descriptor.value = Zone.current.wrap(descriptor.value, source);\n _redefineProperty(opts.prototype, callback, descriptor);\n }\n else {\n opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source);\n }\n }\n else if (opts.prototype[callback]) {\n opts.prototype[callback] = Zone.current.wrap(opts.prototype[callback], source);\n }\n });\n }\n return _registerElement.apply(document, [name, opts]);\n };\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nvar set = 'set';\nvar clear = 'clear';\nvar blockingMethods = ['alert', 'prompt', 'confirm'];\nvar _global = typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global;\npatchTimer(_global, set, clear, 'Timeout');\npatchTimer(_global, set, clear, 'Interval');\npatchTimer(_global, set, clear, 'Immediate');\npatchTimer(_global, 'request', 'cancel', 'AnimationFrame');\npatchTimer(_global, 'mozRequest', 'mozCancel', 'AnimationFrame');\npatchTimer(_global, 'webkitRequest', 'webkitCancel', 'AnimationFrame');\nfor (var i = 0; i < blockingMethods.length; i++) {\n var name_1 = blockingMethods[i];\n patchMethod(_global, name_1, function (delegate, symbol, name) {\n return function (s, args) {\n return Zone.current.run(delegate, _global, args, name);\n };\n });\n}\neventTargetPatch(_global);\n// patch XMLHttpRequestEventTarget's addEventListener/removeEventListener\nvar XMLHttpRequestEventTarget = _global['XMLHttpRequestEventTarget'];\nif (XMLHttpRequestEventTarget && XMLHttpRequestEventTarget.prototype) {\n patchEventTargetMethods(XMLHttpRequestEventTarget.prototype);\n}\npropertyDescriptorPatch(_global);\npatchClass('MutationObserver');\npatchClass('WebKitMutationObserver');\npatchClass('FileReader');\npropertyPatch();\nregisterElementPatch(_global);\n// Treat XMLHTTPRequest as a macrotask.\npatchXHR(_global);\nvar XHR_TASK = zoneSymbol('xhrTask');\nvar XHR_SYNC = zoneSymbol('xhrSync');\nvar XHR_LISTENER = zoneSymbol('xhrListener');\nvar XHR_SCHEDULED = zoneSymbol('xhrScheduled');\nfunction patchXHR(window) {\n function findPendingTask(target) {\n var pendingTask = target[XHR_TASK];\n return pendingTask;\n }\n function scheduleTask(task) {\n XMLHttpRequest[XHR_SCHEDULED] = false;\n var data = task.data;\n // remove existing event listener\n var listener = data.target[XHR_LISTENER];\n if (listener) {\n data.target.removeEventListener('readystatechange', listener);\n }\n var newListener = data.target[XHR_LISTENER] = function () {\n if (data.target.readyState === data.target.DONE) {\n // sometimes on some browsers XMLHttpRequest will fire onreadystatechange with\n // readyState=4 multiple times, so we need to check task state here\n if (!data.aborted && XMLHttpRequest[XHR_SCHEDULED] && task.state === 'scheduled') {\n task.invoke();\n }\n }\n };\n data.target.addEventListener('readystatechange', newListener);\n var storedTask = data.target[XHR_TASK];\n if (!storedTask) {\n data.target[XHR_TASK] = task;\n }\n sendNative.apply(data.target, data.args);\n XMLHttpRequest[XHR_SCHEDULED] = true;\n return task;\n }\n function placeholderCallback() { }\n function clearTask(task) {\n var data = task.data;\n // Note - ideally, we would call data.target.removeEventListener here, but it's too late\n // to prevent it from firing. So instead, we store info for the event listener.\n data.aborted = true;\n return abortNative.apply(data.target, data.args);\n }\n var openNative = patchMethod(window.XMLHttpRequest.prototype, 'open', function () { return function (self, args) {\n self[XHR_SYNC] = args[2] == false;\n return openNative.apply(self, args);\n }; });\n var sendNative = patchMethod(window.XMLHttpRequest.prototype, 'send', function () { return function (self, args) {\n var zone = Zone.current;\n if (self[XHR_SYNC]) {\n // if the XHR is sync there is no task to schedule, just execute the code.\n return sendNative.apply(self, args);\n }\n else {\n var options = { target: self, isPeriodic: false, delay: null, args: args, aborted: false };\n return zone.scheduleMacroTask('XMLHttpRequest.send', placeholderCallback, options, scheduleTask, clearTask);\n }\n }; });\n var abortNative = patchMethod(window.XMLHttpRequest.prototype, 'abort', function (delegate) { return function (self, args) {\n var task = findPendingTask(self);\n if (task && typeof task.type == 'string') {\n // If the XHR has already completed, do nothing.\n // If the XHR has already been aborted, do nothing.\n // Fix #569, call abort multiple times before done will cause\n // macroTask task count be negative number\n if (task.cancelFn == null || (task.data && task.data.aborted)) {\n return;\n }\n task.zone.cancelTask(task);\n }\n // Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no task\n // to cancel. Do nothing.\n }; });\n}\n/// GEO_LOCATION\nif (_global['navigator'] && _global['navigator'].geolocation) {\n patchPrototype(_global['navigator'].geolocation, ['getCurrentPosition', 'watchPosition']);\n}\n// handle unhandled promise rejection\nfunction findPromiseRejectionHandler(evtName) {\n return function (e) {\n var eventTasks = findEventTask(_global, evtName);\n eventTasks.forEach(function (eventTask) {\n // windows has added unhandledrejection event listener\n // trigger the event listener\n var PromiseRejectionEvent = _global['PromiseRejectionEvent'];\n if (PromiseRejectionEvent) {\n var evt = new PromiseRejectionEvent(evtName, { promise: e.promise, reason: e.rejection });\n eventTask.invoke(evt);\n }\n });\n };\n}\nif (_global['PromiseRejectionEvent']) {\n Zone[zoneSymbol('unhandledPromiseRejectionHandler')] =\n findPromiseRejectionHandler('unhandledrejection');\n Zone[zoneSymbol('rejectionHandledHandler')] =\n findPromiseRejectionHandler('rejectionhandled');\n}\n\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n})));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/zone.js/dist/zone.js\n// module id = 175\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js.map b/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js.map deleted file mode 100644 index 1b12d47fe8..0000000000 --- a/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/styles.bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///./~/css-loader/lib/css-base.js","webpack:///./~/bootstrap/dist/css/bootstrap.min.css","webpack:///./src/styles.css","webpack:///./~/style-loader/addStyles.js","webpack:///./~/bootstrap/dist/css/bootstrap.min.css?fb7d","webpack:///./src/styles.css?c4d3"],"names":[],"mappings":"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AACA;;;AAGA;AACA;;AAEA;;;;;;;;;;;;;;;;;ACPA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sBAAsB;AACtC;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,iBAAiB,2BAA2B;AAC5C;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA;AACA,GAAG;AACH;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;;AAEA;AACA;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,GAAG;AACH;AACA;AACA;AACA,EAAE;AACF;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uDAAuD;AACvD;;AAEA,6BAA6B,mBAAmB;;AAEhD;;AAEA;;AAEA;AACA;AACA;;;;;;;;ACrPA;;AAEA;AACA,qCAA+F;AAC/F;AACA;AACA,gDAAuE;AACvE;AACA;AACA;AACA;AACA;AACA,qDAAqD,wCAAwC;AAC7F,6DAA6D,wCAAwC;AACrG;AACA;AACA,GAAG;AACH;AACA;AACA,gCAAgC,UAAU,EAAE;AAC5C,C;;;;;;;ACpBA;;AAEA;AACA,qCAAsG;AACtG;AACA;AACA,gDAA8E;AAC9E;AACA;AACA;AACA;AACA;AACA,4DAA4D,wCAAwC;AACpG,oEAAoE,wCAAwC;AAC5G;AACA;AACA,GAAG;AACH;AACA;AACA,gCAAgC,UAAU,EAAE;AAC5C,C","file":"styles.bundle.js","sourcesContent":["/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\nmodule.exports = function() {\n\tvar list = [];\n\n\t// return the list of modules as css string\n\tlist.toString = function toString() {\n\t\tvar result = [];\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar item = this[i];\n\t\t\tif(item[2]) {\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\n\t\t\t} else {\n\t\t\t\tresult.push(item[1]);\n\t\t\t}\n\t\t}\n\t\treturn result.join(\"\");\n\t};\n\n\t// import a list of modules into the list\n\tlist.i = function(modules, mediaQuery) {\n\t\tif(typeof modules === \"string\")\n\t\t\tmodules = [[null, modules, \"\"]];\n\t\tvar alreadyImportedModules = {};\n\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\tvar id = this[i][0];\n\t\t\tif(typeof id === \"number\")\n\t\t\t\talreadyImportedModules[id] = true;\n\t\t}\n\t\tfor(i = 0; i < modules.length; i++) {\n\t\t\tvar item = modules[i];\n\t\t\t// skip already imported module\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\n\t\t\t// when a module is imported multiple times with different media queries.\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\n\t\t\t\tif(mediaQuery && !item[2]) {\n\t\t\t\t\titem[2] = mediaQuery;\n\t\t\t\t} else if(mediaQuery) {\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\n\t\t\t\t}\n\t\t\t\tlist.push(item);\n\t\t\t}\n\t\t}\n\t};\n\treturn list;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 13\n// module chunks = 2 3","exports = module.exports = require(\"../../../css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/*!\\n * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com)\\n * Copyright 2011-2017 The Bootstrap Authors\\n * Copyright 2011-2017 Twitter, Inc.\\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\\n *//*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}@media print{*,::after,::before,blockquote::first-letter,blockquote::first-line,div::first-letter,div::first-line,li::first-letter,li::first-line,p::first-letter,p::first-line{text-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}abbr[title]::after{content:\\\" (\\\" attr(title) \\\")\\\"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}@-ms-viewport{width:device-width}html{-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,\\\"Segoe UI\\\",Roboto,\\\"Helvetica Neue\\\",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#292b2c;background-color:#fff}[tabindex=\\\"-1\\\"]:focus{outline:0!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#0275d8;text-decoration:none}a:focus,a:hover{color:#014c8c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#636c72;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.1}.display-2{font-size:5.5rem;font-weight:300;line-height:1.1}.display-3{font-size:4.5rem;font-weight:300;line-height:1.1}.display-4{font-size:3.5rem;font-weight:300;line-height:1.1}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:5px}.initialism{font-size:90%;text-transform:uppercase}.blockquote{padding:.5rem 1rem;margin-bottom:1rem;font-size:1.25rem;border-left:.25rem solid #eceeef}.blockquote-footer{display:block;font-size:80%;color:#636c72}.blockquote-footer::before{content:\\\"\\\\2014 \\\\A0\\\"}.blockquote-reverse{padding-right:1rem;padding-left:0;text-align:right;border-right:.25rem solid #eceeef;border-left:0}.blockquote-reverse .blockquote-footer::before{content:\\\"\\\"}.blockquote-reverse .blockquote-footer::after{content:\\\"\\\\A0 \\\\2014\\\"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #ddd;border-radius:.25rem;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#636c72}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,\\\"Liberation Mono\\\",\\\"Courier New\\\",monospace}code{padding:.2rem .4rem;font-size:90%;color:#bd4147;background-color:#f7f7f9;border-radius:.25rem}a>code{padding:0;color:inherit;background-color:inherit}kbd{padding:.2rem .4rem;font-size:90%;color:#fff;background-color:#292b2c;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;margin-top:0;margin-bottom:1rem;font-size:90%;color:#292b2c}pre code{padding:0;font-size:inherit;color:inherit;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{position:relative;margin-left:auto;margin-right:auto;padding-right:15px;padding-left:15px}@media (min-width:576px){.container{padding-right:15px;padding-left:15px}}@media (min-width:768px){.container{padding-right:15px;padding-left:15px}}@media (min-width:992px){.container{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.container{padding-right:15px;padding-left:15px}}@media (min-width:576px){.container{width:540px;max-width:100%}}@media (min-width:768px){.container{width:720px;max-width:100%}}@media (min-width:992px){.container{width:960px;max-width:100%}}@media (min-width:1200px){.container{width:1140px;max-width:100%}}.container-fluid{position:relative;margin-left:auto;margin-right:auto;padding-right:15px;padding-left:15px}@media (min-width:576px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:768px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:992px){.container-fluid{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.container-fluid{padding-right:15px;padding-left:15px}}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}@media (min-width:576px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:768px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:992px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:1200px){.row{margin-right:-15px;margin-left:-15px}}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:576px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:768px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:992px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{padding-right:15px;padding-left:15px}}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-0{right:auto}.pull-1{right:8.333333%}.pull-2{right:16.666667%}.pull-3{right:25%}.pull-4{right:33.333333%}.pull-5{right:41.666667%}.pull-6{right:50%}.pull-7{right:58.333333%}.pull-8{right:66.666667%}.pull-9{right:75%}.pull-10{right:83.333333%}.pull-11{right:91.666667%}.pull-12{right:100%}.push-0{left:auto}.push-1{left:8.333333%}.push-2{left:16.666667%}.push-3{left:25%}.push-4{left:33.333333%}.push-5{left:41.666667%}.push-6{left:50%}.push-7{left:58.333333%}.push-8{left:66.666667%}.push-9{left:75%}.push-10{left:83.333333%}.push-11{left:91.666667%}.push-12{left:100%}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-sm-0{right:auto}.pull-sm-1{right:8.333333%}.pull-sm-2{right:16.666667%}.pull-sm-3{right:25%}.pull-sm-4{right:33.333333%}.pull-sm-5{right:41.666667%}.pull-sm-6{right:50%}.pull-sm-7{right:58.333333%}.pull-sm-8{right:66.666667%}.pull-sm-9{right:75%}.pull-sm-10{right:83.333333%}.pull-sm-11{right:91.666667%}.pull-sm-12{right:100%}.push-sm-0{left:auto}.push-sm-1{left:8.333333%}.push-sm-2{left:16.666667%}.push-sm-3{left:25%}.push-sm-4{left:33.333333%}.push-sm-5{left:41.666667%}.push-sm-6{left:50%}.push-sm-7{left:58.333333%}.push-sm-8{left:66.666667%}.push-sm-9{left:75%}.push-sm-10{left:83.333333%}.push-sm-11{left:91.666667%}.push-sm-12{left:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-md-0{right:auto}.pull-md-1{right:8.333333%}.pull-md-2{right:16.666667%}.pull-md-3{right:25%}.pull-md-4{right:33.333333%}.pull-md-5{right:41.666667%}.pull-md-6{right:50%}.pull-md-7{right:58.333333%}.pull-md-8{right:66.666667%}.pull-md-9{right:75%}.pull-md-10{right:83.333333%}.pull-md-11{right:91.666667%}.pull-md-12{right:100%}.push-md-0{left:auto}.push-md-1{left:8.333333%}.push-md-2{left:16.666667%}.push-md-3{left:25%}.push-md-4{left:33.333333%}.push-md-5{left:41.666667%}.push-md-6{left:50%}.push-md-7{left:58.333333%}.push-md-8{left:66.666667%}.push-md-9{left:75%}.push-md-10{left:83.333333%}.push-md-11{left:91.666667%}.push-md-12{left:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-lg-0{right:auto}.pull-lg-1{right:8.333333%}.pull-lg-2{right:16.666667%}.pull-lg-3{right:25%}.pull-lg-4{right:33.333333%}.pull-lg-5{right:41.666667%}.pull-lg-6{right:50%}.pull-lg-7{right:58.333333%}.pull-lg-8{right:66.666667%}.pull-lg-9{right:75%}.pull-lg-10{right:83.333333%}.pull-lg-11{right:91.666667%}.pull-lg-12{right:100%}.push-lg-0{left:auto}.push-lg-1{left:8.333333%}.push-lg-2{left:16.666667%}.push-lg-3{left:25%}.push-lg-4{left:33.333333%}.push-lg-5{left:41.666667%}.push-lg-6{left:50%}.push-lg-7{left:58.333333%}.push-lg-8{left:66.666667%}.push-lg-9{left:75%}.push-lg-10{left:83.333333%}.push-lg-11{left:91.666667%}.push-lg-12{left:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.pull-xl-0{right:auto}.pull-xl-1{right:8.333333%}.pull-xl-2{right:16.666667%}.pull-xl-3{right:25%}.pull-xl-4{right:33.333333%}.pull-xl-5{right:41.666667%}.pull-xl-6{right:50%}.pull-xl-7{right:58.333333%}.pull-xl-8{right:66.666667%}.pull-xl-9{right:75%}.pull-xl-10{right:83.333333%}.pull-xl-11{right:91.666667%}.pull-xl-12{right:100%}.push-xl-0{left:auto}.push-xl-1{left:8.333333%}.push-xl-2{left:16.666667%}.push-xl-3{left:25%}.push-xl-4{left:33.333333%}.push-xl-5{left:41.666667%}.push-xl-6{left:50%}.push-xl-7{left:58.333333%}.push-xl-8{left:66.666667%}.push-xl-9{left:75%}.push-xl-10{left:83.333333%}.push-xl-11{left:91.666667%}.push-xl-12{left:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #eceeef}.table thead th{vertical-align:bottom;border-bottom:2px solid #eceeef}.table tbody+tbody{border-top:2px solid #eceeef}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #eceeef}.table-bordered td,.table-bordered th{border:1px solid #eceeef}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table-success,.table-success>td,.table-success>th{background-color:#dff0d8}.table-hover .table-success:hover{background-color:#d0e9c6}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#d0e9c6}.table-info,.table-info>td,.table-info>th{background-color:#d9edf7}.table-hover .table-info:hover{background-color:#c4e3f3}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c4e3f3}.table-warning,.table-warning>td,.table-warning>th{background-color:#fcf8e3}.table-hover .table-warning:hover{background-color:#faf2cc}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#faf2cc}.table-danger,.table-danger>td,.table-danger>th{background-color:#f2dede}.table-hover .table-danger:hover{background-color:#ebcccc}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#ebcccc}.thead-inverse th{color:#fff;background-color:#292b2c}.thead-default th{color:#464a4c;background-color:#eceeef}.table-inverse{color:#fff;background-color:#292b2c}.table-inverse td,.table-inverse th,.table-inverse thead th{border-color:#fff}.table-inverse.table-bordered{border:0}.table-responsive{display:block;width:100%;overflow-x:auto;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive.table-bordered{border:0}.form-control{display:block;width:100%;padding:.5rem .75rem;font-size:1rem;line-height:1.25;color:#464a4c;background-color:#fff;background-image:none;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#464a4c;background-color:#fff;border-color:#5cb3fd;outline:0}.form-control::-webkit-input-placeholder{color:#636c72;opacity:1}.form-control:-ms-input-placeholder{color:#636c72;opacity:1}.form-control::placeholder{color:#636c72;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#eceeef;opacity:1}.form-control:disabled{cursor:not-allowed}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#464a4c;background-color:#fff}.form-control-file,.form-control-range{display:block}.col-form-label{padding-top:calc(.5rem - 1px * 2);padding-bottom:calc(.5rem - 1px * 2);margin-bottom:0}.col-form-label-lg{padding-top:calc(.75rem - 1px * 2);padding-bottom:calc(.75rem - 1px * 2);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem - 1px * 2);padding-bottom:calc(.25rem - 1px * 2);font-size:.875rem}.col-form-legend{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0;font-size:1rem}.form-control-static{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0;line-height:1.25;border:solid transparent;border-width:1px 0}.form-control-static.form-control-lg,.form-control-static.form-control-sm,.input-group-lg>.form-control-static.form-control,.input-group-lg>.form-control-static.input-group-addon,.input-group-lg>.input-group-btn>.form-control-static.btn,.input-group-sm>.form-control-static.form-control,.input-group-sm>.form-control-static.input-group-addon,.input-group-sm>.input-group-btn>.form-control-static.btn{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-sm>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>select.input-group-addon:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:1.8125rem}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.input-group-lg>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>select.input-group-addon:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:3.166667rem}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-check{position:relative;display:block;margin-bottom:.5rem}.form-check.disabled .form-check-label{color:#636c72;cursor:not-allowed}.form-check-label{padding-left:1.25rem;margin-bottom:0;cursor:pointer}.form-check-input{position:absolute;margin-top:.25rem;margin-left:-1.25rem}.form-check-input:only-child{position:static}.form-check-inline{display:inline-block}.form-check-inline .form-check-label{vertical-align:middle}.form-check-inline+.form-check-inline{margin-left:.75rem}.form-control-feedback{margin-top:.25rem}.form-control-danger,.form-control-success,.form-control-warning{padding-right:2.25rem;background-repeat:no-repeat;background-position:center right .5625rem;background-size:1.125rem 1.125rem}.has-success .col-form-label,.has-success .custom-control,.has-success .form-check-label,.has-success .form-control-feedback,.has-success .form-control-label{color:#5cb85c}.has-success .form-control{border-color:#5cb85c}.has-success .input-group-addon{color:#5cb85c;border-color:#5cb85c;background-color:#eaf6ea}.has-success .form-control-success{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%235cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E\\\")}.has-warning .col-form-label,.has-warning .custom-control,.has-warning .form-check-label,.has-warning .form-control-feedback,.has-warning .form-control-label{color:#f0ad4e}.has-warning .form-control{border-color:#f0ad4e}.has-warning .input-group-addon{color:#f0ad4e;border-color:#f0ad4e;background-color:#fff}.has-warning .form-control-warning{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23f0ad4e' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E\\\")}.has-danger .col-form-label,.has-danger .custom-control,.has-danger .form-check-label,.has-danger .form-control-feedback,.has-danger .form-control-label{color:#d9534f}.has-danger .form-control{border-color:#d9534f}.has-danger .input-group-addon{color:#d9534f;border-color:#d9534f;background-color:#fdf7f7}.has-danger .form-control-danger{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E\\\")}.form-inline{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{width:auto}.form-inline .form-control-label{margin-bottom:0;vertical-align:middle}.form-inline .form-check{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto;margin-top:0;margin-bottom:0}.form-inline .form-check-label{padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0}.form-inline .custom-control-indicator{position:static;display:inline-block;margin-right:.25rem;vertical-align:text-bottom}.form-inline .has-feedback .form-control-feedback{top:0}}.btn{display:inline-block;font-weight:400;line-height:1.25;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.5rem 1rem;font-size:1rem;border-radius:.25rem;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 2px rgba(2,117,216,.25)}.btn.disabled,.btn:disabled{cursor:not-allowed;opacity:.65}.btn.active,.btn:active{background-image:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-primary:hover{color:#fff;background-color:#025aa5;border-color:#01549b}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 2px rgba(2,117,216,.5)}.btn-primary.disabled,.btn-primary:disabled{background-color:#0275d8;border-color:#0275d8}.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#025aa5;background-image:none;border-color:#01549b}.btn-secondary{color:#292b2c;background-color:#fff;border-color:#ccc}.btn-secondary:hover{color:#292b2c;background-color:#e6e6e6;border-color:#adadad}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 2px rgba(204,204,204,.5)}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#fff;border-color:#ccc}.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#292b2c;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#2aabd2}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 2px rgba(91,192,222,.5)}.btn-info.disabled,.btn-info:disabled{background-color:#5bc0de;border-color:#5bc0de}.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;background-image:none;border-color:#2aabd2}.btn-success{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#419641}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 2px rgba(92,184,92,.5)}.btn-success.disabled,.btn-success:disabled{background-color:#5cb85c;border-color:#5cb85c}.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#449d44;background-image:none;border-color:#419641}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#eb9316}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 2px rgba(240,173,78,.5)}.btn-warning.disabled,.btn-warning:disabled{background-color:#f0ad4e;border-color:#f0ad4e}.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#ec971f;background-image:none;border-color:#eb9316}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#c12e2a}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 2px rgba(217,83,79,.5)}.btn-danger.disabled,.btn-danger:disabled{background-color:#d9534f;border-color:#d9534f}.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#c9302c;background-image:none;border-color:#c12e2a}.btn-outline-primary{color:#0275d8;background-image:none;background-color:transparent;border-color:#0275d8}.btn-outline-primary:hover{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 2px rgba(2,117,216,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0275d8;background-color:transparent}.btn-outline-primary.active,.btn-outline-primary:active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#0275d8;border-color:#0275d8}.btn-outline-secondary{color:#ccc;background-image:none;background-color:transparent;border-color:#ccc}.btn-outline-secondary:hover{color:#fff;background-color:#ccc;border-color:#ccc}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 2px rgba(204,204,204,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#ccc;background-color:transparent}.btn-outline-secondary.active,.btn-outline-secondary:active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#ccc;border-color:#ccc}.btn-outline-info{color:#5bc0de;background-image:none;background-color:transparent;border-color:#5bc0de}.btn-outline-info:hover{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 2px rgba(91,192,222,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#5bc0de;background-color:transparent}.btn-outline-info.active,.btn-outline-info:active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-success{color:#5cb85c;background-image:none;background-color:transparent;border-color:#5cb85c}.btn-outline-success:hover{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 2px rgba(92,184,92,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#5cb85c;background-color:transparent}.btn-outline-success.active,.btn-outline-success:active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#5cb85c;border-color:#5cb85c}.btn-outline-warning{color:#f0ad4e;background-image:none;background-color:transparent;border-color:#f0ad4e}.btn-outline-warning:hover{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 2px rgba(240,173,78,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#f0ad4e;background-color:transparent}.btn-outline-warning.active,.btn-outline-warning:active,.show>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#f0ad4e;border-color:#f0ad4e}.btn-outline-danger{color:#d9534f;background-image:none;background-color:transparent;border-color:#d9534f}.btn-outline-danger:hover{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 2px rgba(217,83,79,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#d9534f;background-color:transparent}.btn-outline-danger.active,.btn-outline-danger:active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#d9534f;border-color:#d9534f}.btn-link{font-weight:400;color:#0275d8;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link:disabled{background-color:transparent}.btn-link,.btn-link:active,.btn-link:focus{border-color:transparent}.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#014c8c;text-decoration:underline;background-color:transparent}.btn-link:disabled{color:#636c72}.btn-link:disabled:focus,.btn-link:disabled:hover{text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.3em;vertical-align:middle;content:\\\"\\\";border-top:.3em solid;border-right:.3em solid transparent;border-left:.3em solid transparent}.dropdown-toggle:focus{outline:0}.dropup .dropdown-toggle::after{border-top:0;border-bottom:.3em solid}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#292b2c;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-divider{height:1px;margin:.5rem 0;overflow:hidden;background-color:#eceeef}.dropdown-item{display:block;width:100%;padding:3px 1.5rem;clear:both;font-weight:400;color:#292b2c;text-align:inherit;white-space:nowrap;background:0 0;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1d1e1f;text-decoration:none;background-color:#f7f7f9}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0275d8}.dropdown-item.disabled,.dropdown-item:disabled{color:#636c72;cursor:not-allowed;background-color:transparent}.show>.dropdown-menu{display:block}.show>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#636c72;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.dropup .dropdown-menu{top:auto;bottom:100%;margin-bottom:.125rem}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:2}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn+.dropdown-toggle-split::after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:1.125rem;padding-left:1.125rem}.btn-group-vertical{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%}.input-group .form-control{position:relative;z-index:2;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group .form-control:active,.input-group .form-control:focus,.input-group .form-control:hover{z-index:3}.input-group .form-control,.input-group-addon,.input-group-btn{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{white-space:nowrap;vertical-align:middle}.input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#464a4c;text-align:center;background-color:#eceeef;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.input-group-addon.form-control-sm,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.input-group-addon.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-addon.form-control-lg,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.input-group-addon.btn{padding:.75rem 1.5rem;font-size:1.25rem;border-radius:.3rem}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:not(:last-child),.input-group-addon:not(:last-child),.input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group>.btn,.input-group-btn:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:not(:last-child){border-right:0}.input-group .form-control:not(:first-child),.input-group-addon:not(:first-child),.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group>.btn,.input-group-btn:not(:first-child)>.dropdown-toggle,.input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.input-group-btn:not(:last-child)>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.form-control+.input-group-addon:not(:first-child){border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative;-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:3}.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group{margin-right:-1px}.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-left:-1px}.input-group-btn:not(:first-child)>.btn-group:active,.input-group-btn:not(:first-child)>.btn-group:focus,.input-group-btn:not(:first-child)>.btn-group:hover,.input-group-btn:not(:first-child)>.btn:active,.input-group-btn:not(:first-child)>.btn:focus,.input-group-btn:not(:first-child)>.btn:hover{z-index:3}.custom-control{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;min-height:1.5rem;padding-left:1.5rem;margin-right:1rem;cursor:pointer}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-indicator{color:#fff;background-color:#0275d8}.custom-control-input:focus~.custom-control-indicator{box-shadow:0 0 0 1px #fff,0 0 0 3px #0275d8}.custom-control-input:active~.custom-control-indicator{color:#fff;background-color:#8fcafe}.custom-control-input:disabled~.custom-control-indicator{cursor:not-allowed;background-color:#eceeef}.custom-control-input:disabled~.custom-control-description{color:#636c72;cursor:not-allowed}.custom-control-indicator{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#ddd;background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-indicator{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-indicator{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E\\\")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-indicator{background-color:#0275d8;background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E\\\")}.custom-radio .custom-control-indicator{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-indicator{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E\\\")}.custom-controls-stacked{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.custom-controls-stacked .custom-control{margin-bottom:.25rem}.custom-controls-stacked .custom-control+.custom-control{margin-left:0}.custom-select{display:inline-block;max-width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.25;color:#464a4c;vertical-align:middle;background:#fff url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E\\\") no-repeat right .75rem center;background-size:8px 10px;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;-moz-appearance:none;-webkit-appearance:none}.custom-select:focus{border-color:#5cb3fd;outline:0}.custom-select:focus::-ms-value{color:#464a4c;background-color:#fff}.custom-select:disabled{color:#636c72;cursor:not-allowed;background-color:#eceeef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-file{position:relative;display:inline-block;max-width:100%;height:2.5rem;margin-bottom:0;cursor:pointer}.custom-file-input{min-width:14rem;max-width:100%;height:2.5rem;margin:0;filter:alpha(opacity=0);opacity:0}.custom-file-control{position:absolute;top:0;right:0;left:0;z-index:5;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#464a4c;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.custom-file-control:lang(en)::after{content:\\\"Choose file...\\\"}.custom-file-control::before{position:absolute;top:-1px;right:-1px;bottom:-1px;z-index:6;display:block;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#464a4c;background-color:#eceeef;border:1px solid rgba(0,0,0,.15);border-radius:0 .25rem .25rem 0}.custom-file-control:lang(en)::before{content:\\\"Browse\\\"}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5em 1em}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#636c72;cursor:not-allowed}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-right-radius:.25rem;border-top-left-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#eceeef #eceeef #ddd}.nav-tabs .nav-link.disabled{color:#636c72;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#464a4c;background-color:#fff;border-color:#ddd #ddd #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-item.show .nav-link,.nav-pills .nav-link.active{color:#fff;cursor:default;background-color:#0275d8}.nav-fill .nav-item{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-webkit-box-flex:1;-ms-flex:1 1 100%;flex:1 1 100%;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:.5rem 1rem}.navbar-brand{display:inline-block;padding-top:.25rem;padding-bottom:.25rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-text{display:inline-block;padding-top:.425rem;padding-bottom:.425rem}.navbar-toggler{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start;padding:.25rem .75rem;font-size:1.25rem;line-height:1;background:0 0;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:\\\"\\\";background:no-repeat center center;background-size:100% 100%}.navbar-toggler-left{position:absolute;left:1rem}.navbar-toggler-right{position:absolute;right:1rem}@media (max-width:575px){.navbar-toggleable .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable>.container{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-toggleable{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable>.container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable .navbar-toggler{display:none}}@media (max-width:767px){.navbar-toggleable-sm .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-sm>.container{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-toggleable-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-sm>.container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-sm .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-sm .navbar-toggler{display:none}}@media (max-width:991px){.navbar-toggleable-md .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-md>.container{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-toggleable-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-md>.container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-md .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-md .navbar-toggler{display:none}}@media (max-width:1199px){.navbar-toggleable-lg .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-lg>.container{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-toggleable-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-lg>.container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-lg .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-lg .navbar-toggler{display:none}}.navbar-toggleable-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-xl .navbar-nav .dropdown-menu{position:static;float:none}.navbar-toggleable-xl>.container{padding-right:0;padding-left:0}.navbar-toggleable-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-toggleable-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-toggleable-xl>.container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggleable-xl .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;width:100%}.navbar-toggleable-xl .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-toggler{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover,.navbar-light .navbar-toggler:focus,.navbar-light .navbar-toggler:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.open,.navbar-light .navbar-nav .open>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E\\\")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-toggler{color:#fff}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-toggler:focus,.navbar-inverse .navbar-toggler:hover{color:#fff}.navbar-inverse .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-inverse .navbar-nav .nav-link:focus,.navbar-inverse .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-inverse .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-inverse .navbar-nav .active>.nav-link,.navbar-inverse .navbar-nav .nav-link.active,.navbar-inverse .navbar-nav .nav-link.open,.navbar-inverse .navbar-nav .open>.nav-link{color:#fff}.navbar-inverse .navbar-toggler{border-color:rgba(255,255,255,.1)}.navbar-inverse .navbar-toggler-icon{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E\\\")}.navbar-inverse .navbar-text{color:rgba(255,255,255,.5)}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background-color:#fff;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card-block{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card>.list-group:first-child .list-group-item:first-child{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#f7f7f9;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:#f7f7f9;border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-primary{background-color:#0275d8;border-color:#0275d8}.card-primary .card-footer,.card-primary .card-header{background-color:transparent}.card-success{background-color:#5cb85c;border-color:#5cb85c}.card-success .card-footer,.card-success .card-header{background-color:transparent}.card-info{background-color:#5bc0de;border-color:#5bc0de}.card-info .card-footer,.card-info .card-header{background-color:transparent}.card-warning{background-color:#f0ad4e;border-color:#f0ad4e}.card-warning .card-footer,.card-warning .card-header{background-color:transparent}.card-danger{background-color:#d9534f;border-color:#d9534f}.card-danger .card-footer,.card-danger .card-header{background-color:transparent}.card-outline-primary{background-color:transparent;border-color:#0275d8}.card-outline-secondary{background-color:transparent;border-color:#ccc}.card-outline-info{background-color:transparent;border-color:#5bc0de}.card-outline-success{background-color:transparent;border-color:#5cb85c}.card-outline-warning{background-color:transparent;border-color:#f0ad4e}.card-outline-danger{background-color:transparent;border-color:#d9534f}.card-inverse{color:rgba(255,255,255,.65)}.card-inverse .card-footer,.card-inverse .card-header{background-color:transparent;border-color:rgba(255,255,255,.2)}.card-inverse .card-blockquote,.card-inverse .card-footer,.card-inverse .card-header,.card-inverse .card-title{color:#fff}.card-inverse .card-blockquote .blockquote-footer,.card-inverse .card-link,.card-inverse .card-subtitle,.card-inverse .card-text{color:rgba(255,255,255,.65)}.card-inverse .card-link:focus,.card-inverse .card-link:hover{color:#fff}.card-blockquote{padding:0;margin-bottom:0;border-left:0}.card-img{border-radius:calc(.25rem - 1px)}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img-top{border-top-right-radius:calc(.25rem - 1px);border-top-left-radius:calc(.25rem - 1px)}.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}@media (min-width:576px){.card-deck{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap}.card-deck .card{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card:not(:first-child){margin-left:15px}.card-deck .card:not(:last-child){margin-right:15px}}@media (min-width:576px){.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap}.card-group .card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.card-group .card+.card{margin-left:0;border-left:0}.card-group .card:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.card-group .card:first-child .card-img-top{border-top-right-radius:0}.card-group .card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group .card:last-child{border-bottom-left-radius:0;border-top-left-radius:0}.card-group .card:last-child .card-img-top{border-top-left-radius:0}.card-group .card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group .card:not(:first-child):not(:last-child){border-radius:0}.card-group .card:not(:first-child):not(:last-child) .card-img-bottom,.card-group .card:not(:first-child):not(:last-child) .card-img-top{border-radius:0}}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%;margin-bottom:.75rem}}.breadcrumb{padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#eceeef;border-radius:.25rem}.breadcrumb::after{display:block;content:\\\"\\\";clear:both}.breadcrumb-item{float:left}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#636c72;content:\\\"/\\\"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#636c72}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-item:first-child .page-link{margin-left:0;border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.page-item.active .page-link{z-index:2;color:#fff;background-color:#0275d8;border-color:#0275d8}.page-item.disabled .page-link{color:#636c72;pointer-events:none;cursor:not-allowed;background-color:#fff;border-color:#ddd}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#0275d8;background-color:#fff;border:1px solid #ddd}.page-link:focus,.page-link:hover{color:#014c8c;text-decoration:none;background-color:#eceeef;border-color:#ddd}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-default{background-color:#636c72}.badge-default[href]:focus,.badge-default[href]:hover{background-color:#4b5257}.badge-primary{background-color:#0275d8}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#025aa5}.badge-success{background-color:#5cb85c}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#449d44}.badge-info{background-color:#5bc0de}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#31b0d5}.badge-warning{background-color:#f0ad4e}.badge-warning[href]:focus,.badge-warning[href]:hover{background-color:#ec971f}.badge-danger{background-color:#d9534f}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#c9302c}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#eceeef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-hr{border-top-color:#d0d5d8}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible .close{position:relative;top:-.75rem;right:-1.25rem;padding:.75rem 1.25rem;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d0e9c6;color:#3c763d}.alert-success hr{border-top-color:#c1e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bcdff1;color:#31708f}.alert-info hr{border-top-color:#a6d5ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faf2cc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7ecb5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebcccc;color:#a94442}.alert-danger hr{border-top-color:#e4b9b9}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;overflow:hidden;font-size:.75rem;line-height:1rem;text-align:center;background-color:#eceeef;border-radius:.25rem}.progress-bar{height:1rem;color:#fff;background-color:#0275d8}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#464a4c;text-align:inherit}.list-group-item-action .list-group-item-heading{color:#292b2c}.list-group-item-action:focus,.list-group-item-action:hover{color:#464a4c;text-decoration:none;background-color:#f7f7f9}.list-group-item-action:active{color:#292b2c;background-color:#eceeef}.list-group-item{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#636c72;cursor:not-allowed;background-color:#fff}.list-group-item.disabled .list-group-item-heading,.list-group-item:disabled .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item:disabled .list-group-item-text{color:#636c72}.list-group-item.active{z-index:2;color:#fff;background-color:#0275d8;border-color:#0275d8}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text{color:#daeeff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active{color:#fff;background-color:#a94442;border-color:#a94442}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:\\\"\\\"}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.75}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out, -webkit-transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:15px;border-bottom:1px solid #eceeef}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:15px}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:15px;border-top:1px solid #eceeef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:30px auto}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:-apple-system,system-ui,BlinkMacSystemFont,\\\"Segoe UI\\\",Roboto,\\\"Helvetica Neue\\\",Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip.bs-tether-element-attached-bottom,.tooltip.tooltip-top{padding:5px 0;margin-top:-3px}.tooltip.bs-tether-element-attached-bottom .tooltip-inner::before,.tooltip.tooltip-top .tooltip-inner::before{bottom:0;left:50%;margin-left:-5px;content:\\\"\\\";border-width:5px 5px 0;border-top-color:#000}.tooltip.bs-tether-element-attached-left,.tooltip.tooltip-right{padding:0 5px;margin-left:3px}.tooltip.bs-tether-element-attached-left .tooltip-inner::before,.tooltip.tooltip-right .tooltip-inner::before{top:50%;left:0;margin-top:-5px;content:\\\"\\\";border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.bs-tether-element-attached-top,.tooltip.tooltip-bottom{padding:5px 0;margin-top:3px}.tooltip.bs-tether-element-attached-top .tooltip-inner::before,.tooltip.tooltip-bottom .tooltip-inner::before{top:0;left:50%;margin-left:-5px;content:\\\"\\\";border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bs-tether-element-attached-right,.tooltip.tooltip-left{padding:0 5px;margin-left:-3px}.tooltip.bs-tether-element-attached-right .tooltip-inner::before,.tooltip.tooltip-left .tooltip-inner::before{top:50%;right:0;margin-top:-5px;content:\\\"\\\";border-width:5px 0 5px 5px;border-left-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.tooltip-inner::before{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;padding:1px;font-family:-apple-system,system-ui,BlinkMacSystemFont,\\\"Segoe UI\\\",Roboto,\\\"Helvetica Neue\\\",Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover.bs-tether-element-attached-bottom,.popover.popover-top{margin-top:-10px}.popover.bs-tether-element-attached-bottom::after,.popover.bs-tether-element-attached-bottom::before,.popover.popover-top::after,.popover.popover-top::before{left:50%;border-bottom-width:0}.popover.bs-tether-element-attached-bottom::before,.popover.popover-top::before{bottom:-11px;margin-left:-11px;border-top-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-bottom::after,.popover.popover-top::after{bottom:-10px;margin-left:-10px;border-top-color:#fff}.popover.bs-tether-element-attached-left,.popover.popover-right{margin-left:10px}.popover.bs-tether-element-attached-left::after,.popover.bs-tether-element-attached-left::before,.popover.popover-right::after,.popover.popover-right::before{top:50%;border-left-width:0}.popover.bs-tether-element-attached-left::before,.popover.popover-right::before{left:-11px;margin-top:-11px;border-right-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-left::after,.popover.popover-right::after{left:-10px;margin-top:-10px;border-right-color:#fff}.popover.bs-tether-element-attached-top,.popover.popover-bottom{margin-top:10px}.popover.bs-tether-element-attached-top::after,.popover.bs-tether-element-attached-top::before,.popover.popover-bottom::after,.popover.popover-bottom::before{left:50%;border-top-width:0}.popover.bs-tether-element-attached-top::before,.popover.popover-bottom::before{top:-11px;margin-left:-11px;border-bottom-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-top::after,.popover.popover-bottom::after{top:-10px;margin-left:-10px;border-bottom-color:#f7f7f7}.popover.bs-tether-element-attached-top .popover-title::before,.popover.popover-bottom .popover-title::before{position:absolute;top:0;left:50%;display:block;width:20px;margin-left:-10px;content:\\\"\\\";border-bottom:1px solid #f7f7f7}.popover.bs-tether-element-attached-right,.popover.popover-left{margin-left:-10px}.popover.bs-tether-element-attached-right::after,.popover.bs-tether-element-attached-right::before,.popover.popover-left::after,.popover.popover-left::before{top:50%;border-right-width:0}.popover.bs-tether-element-attached-right::before,.popover.popover-left::before{right:-11px;margin-top:-11px;border-left-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-right::after,.popover.popover-left::after{right:-10px;margin-top:-10px;border-left-color:#fff}.popover-title{padding:8px 14px;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-right-radius:calc(.3rem - 1px);border-top-left-radius:calc(.3rem - 1px)}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover::after,.popover::before{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover::before{content:\\\"\\\";border-width:11px}.popover::after{content:\\\"\\\";border-width:10px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;width:100%}@media (-webkit-transform-3d){.carousel-item{-webkit-transition:-webkit-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out, -webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}}@supports ((-webkit-transform: translate3d(0,0,0)) or (transform: translate3d(0,0,0))){.carousel-item{-webkit-transition:-webkit-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out, -webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:-webkit-box;display:-ms-flexbox;display:flex}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}@media (-webkit-transform-3d){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@supports ((-webkit-transform: translate3d(0,0,0)) or (transform: translate3d(0,0,0))){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E\\\")}.carousel-control-next-icon{background-image:url(\\\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E\\\")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;max-width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:\\\"\\\"}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:\\\"\\\"}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-faded{background-color:#f7f7f7}.bg-primary{background-color:#0275d8!important}a.bg-primary:focus,a.bg-primary:hover{background-color:#025aa5!important}.bg-success{background-color:#5cb85c!important}a.bg-success:focus,a.bg-success:hover{background-color:#449d44!important}.bg-info{background-color:#5bc0de!important}a.bg-info:focus,a.bg-info:hover{background-color:#31b0d5!important}.bg-warning{background-color:#f0ad4e!important}a.bg-warning:focus,a.bg-warning:hover{background-color:#ec971f!important}.bg-danger{background-color:#d9534f!important}a.bg-danger:focus,a.bg-danger:hover{background-color:#c9302c!important}.bg-inverse{background-color:#292b2c!important}a.bg-inverse:focus,a.bg-inverse:hover{background-color:#101112!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.rounded{border-radius:.25rem}.rounded-top{border-top-right-radius:.25rem;border-top-left-radius:.25rem}.rounded-right{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.rounded-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-left{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-circle{border-radius:50%}.rounded-0{border-radius:0}.clearfix::after{display:block;content:\\\"\\\";clear:both}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flex-last{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.flex-unordered{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flex-sm-last{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.flex-sm-unordered{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-sm-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-sm-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flex-md-last{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.flex-md-unordered{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-md-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-md-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flex-lg-last{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.flex-lg-unordered{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-lg-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-lg-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flex-xl-last{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.flex-xl-unordered{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-webkit-align-self:auto!important;-ms-flex-item-align:auto!important;-ms-grid-row-align:auto!important;align-self:auto!important}.align-self-xl-start{-webkit-align-self:flex-start!important;-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-webkit-align-self:flex-end!important;-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-webkit-align-self:center!important;-ms-flex-item-align:center!important;-ms-grid-row-align:center!important;align-self:center!important}.align-self-xl-baseline{-webkit-align-self:baseline!important;-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-webkit-align-self:stretch!important;-ms-flex-item-align:stretch!important;-ms-grid-row-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1030}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0 0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-right:0!important;margin-left:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:.25rem .25rem!important}.mt-1{margin-top:.25rem!important}.mr-1{margin-right:.25rem!important}.mb-1{margin-bottom:.25rem!important}.ml-1{margin-left:.25rem!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-2{margin:.5rem .5rem!important}.mt-2{margin-top:.5rem!important}.mr-2{margin-right:.5rem!important}.mb-2{margin-bottom:.5rem!important}.ml-2{margin-left:.5rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-3{margin:1rem 1rem!important}.mt-3{margin-top:1rem!important}.mr-3{margin-right:1rem!important}.mb-3{margin-bottom:1rem!important}.ml-3{margin-left:1rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-4{margin:1.5rem 1.5rem!important}.mt-4{margin-top:1.5rem!important}.mr-4{margin-right:1.5rem!important}.mb-4{margin-bottom:1.5rem!important}.ml-4{margin-left:1.5rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-5{margin:3rem 3rem!important}.mt-5{margin-top:3rem!important}.mr-5{margin-right:3rem!important}.mb-5{margin-bottom:3rem!important}.ml-5{margin-left:3rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-0{padding:0 0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-right:0!important;padding-left:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:.25rem .25rem!important}.pt-1{padding-top:.25rem!important}.pr-1{padding-right:.25rem!important}.pb-1{padding-bottom:.25rem!important}.pl-1{padding-left:.25rem!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-2{padding:.5rem .5rem!important}.pt-2{padding-top:.5rem!important}.pr-2{padding-right:.5rem!important}.pb-2{padding-bottom:.5rem!important}.pl-2{padding-left:.5rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-3{padding:1rem 1rem!important}.pt-3{padding-top:1rem!important}.pr-3{padding-right:1rem!important}.pb-3{padding-bottom:1rem!important}.pl-3{padding-left:1rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-4{padding:1.5rem 1.5rem!important}.pt-4{padding-top:1.5rem!important}.pr-4{padding-right:1.5rem!important}.pb-4{padding-bottom:1.5rem!important}.pl-4{padding-left:1.5rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-5{padding:3rem 3rem!important}.pt-5{padding-top:3rem!important}.pr-5{padding-right:3rem!important}.pb-5{padding-bottom:3rem!important}.pl-5{padding-left:3rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-auto{margin:auto!important}.mt-auto{margin-top:auto!important}.mr-auto{margin-right:auto!important}.mb-auto{margin-bottom:auto!important}.ml-auto{margin-left:auto!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}@media (min-width:576px){.m-sm-0{margin:0 0!important}.mt-sm-0{margin-top:0!important}.mr-sm-0{margin-right:0!important}.mb-sm-0{margin-bottom:0!important}.ml-sm-0{margin-left:0!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.m-sm-1{margin:.25rem .25rem!important}.mt-sm-1{margin-top:.25rem!important}.mr-sm-1{margin-right:.25rem!important}.mb-sm-1{margin-bottom:.25rem!important}.ml-sm-1{margin-left:.25rem!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-sm-2{margin:.5rem .5rem!important}.mt-sm-2{margin-top:.5rem!important}.mr-sm-2{margin-right:.5rem!important}.mb-sm-2{margin-bottom:.5rem!important}.ml-sm-2{margin-left:.5rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-sm-3{margin:1rem 1rem!important}.mt-sm-3{margin-top:1rem!important}.mr-sm-3{margin-right:1rem!important}.mb-sm-3{margin-bottom:1rem!important}.ml-sm-3{margin-left:1rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-sm-4{margin:1.5rem 1.5rem!important}.mt-sm-4{margin-top:1.5rem!important}.mr-sm-4{margin-right:1.5rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.ml-sm-4{margin-left:1.5rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-sm-5{margin:3rem 3rem!important}.mt-sm-5{margin-top:3rem!important}.mr-sm-5{margin-right:3rem!important}.mb-sm-5{margin-bottom:3rem!important}.ml-sm-5{margin-left:3rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-sm-0{padding:0 0!important}.pt-sm-0{padding-top:0!important}.pr-sm-0{padding-right:0!important}.pb-sm-0{padding-bottom:0!important}.pl-sm-0{padding-left:0!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.p-sm-1{padding:.25rem .25rem!important}.pt-sm-1{padding-top:.25rem!important}.pr-sm-1{padding-right:.25rem!important}.pb-sm-1{padding-bottom:.25rem!important}.pl-sm-1{padding-left:.25rem!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-sm-2{padding:.5rem .5rem!important}.pt-sm-2{padding-top:.5rem!important}.pr-sm-2{padding-right:.5rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pl-sm-2{padding-left:.5rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-sm-3{padding:1rem 1rem!important}.pt-sm-3{padding-top:1rem!important}.pr-sm-3{padding-right:1rem!important}.pb-sm-3{padding-bottom:1rem!important}.pl-sm-3{padding-left:1rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-sm-4{padding:1.5rem 1.5rem!important}.pt-sm-4{padding-top:1.5rem!important}.pr-sm-4{padding-right:1.5rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pl-sm-4{padding-left:1.5rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-sm-5{padding:3rem 3rem!important}.pt-sm-5{padding-top:3rem!important}.pr-sm-5{padding-right:3rem!important}.pb-sm-5{padding-bottom:3rem!important}.pl-sm-5{padding-left:3rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto{margin-top:auto!important}.mr-sm-auto{margin-right:auto!important}.mb-sm-auto{margin-bottom:auto!important}.ml-sm-auto{margin-left:auto!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:768px){.m-md-0{margin:0 0!important}.mt-md-0{margin-top:0!important}.mr-md-0{margin-right:0!important}.mb-md-0{margin-bottom:0!important}.ml-md-0{margin-left:0!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.m-md-1{margin:.25rem .25rem!important}.mt-md-1{margin-top:.25rem!important}.mr-md-1{margin-right:.25rem!important}.mb-md-1{margin-bottom:.25rem!important}.ml-md-1{margin-left:.25rem!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-md-2{margin:.5rem .5rem!important}.mt-md-2{margin-top:.5rem!important}.mr-md-2{margin-right:.5rem!important}.mb-md-2{margin-bottom:.5rem!important}.ml-md-2{margin-left:.5rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-md-3{margin:1rem 1rem!important}.mt-md-3{margin-top:1rem!important}.mr-md-3{margin-right:1rem!important}.mb-md-3{margin-bottom:1rem!important}.ml-md-3{margin-left:1rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-md-4{margin:1.5rem 1.5rem!important}.mt-md-4{margin-top:1.5rem!important}.mr-md-4{margin-right:1.5rem!important}.mb-md-4{margin-bottom:1.5rem!important}.ml-md-4{margin-left:1.5rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-md-5{margin:3rem 3rem!important}.mt-md-5{margin-top:3rem!important}.mr-md-5{margin-right:3rem!important}.mb-md-5{margin-bottom:3rem!important}.ml-md-5{margin-left:3rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-md-0{padding:0 0!important}.pt-md-0{padding-top:0!important}.pr-md-0{padding-right:0!important}.pb-md-0{padding-bottom:0!important}.pl-md-0{padding-left:0!important}.px-md-0{padding-right:0!important;padding-left:0!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.p-md-1{padding:.25rem .25rem!important}.pt-md-1{padding-top:.25rem!important}.pr-md-1{padding-right:.25rem!important}.pb-md-1{padding-bottom:.25rem!important}.pl-md-1{padding-left:.25rem!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-md-2{padding:.5rem .5rem!important}.pt-md-2{padding-top:.5rem!important}.pr-md-2{padding-right:.5rem!important}.pb-md-2{padding-bottom:.5rem!important}.pl-md-2{padding-left:.5rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-md-3{padding:1rem 1rem!important}.pt-md-3{padding-top:1rem!important}.pr-md-3{padding-right:1rem!important}.pb-md-3{padding-bottom:1rem!important}.pl-md-3{padding-left:1rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-md-4{padding:1.5rem 1.5rem!important}.pt-md-4{padding-top:1.5rem!important}.pr-md-4{padding-right:1.5rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pl-md-4{padding-left:1.5rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-md-5{padding:3rem 3rem!important}.pt-md-5{padding-top:3rem!important}.pr-md-5{padding-right:3rem!important}.pb-md-5{padding-bottom:3rem!important}.pl-md-5{padding-left:3rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto{margin-top:auto!important}.mr-md-auto{margin-right:auto!important}.mb-md-auto{margin-bottom:auto!important}.ml-md-auto{margin-left:auto!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:992px){.m-lg-0{margin:0 0!important}.mt-lg-0{margin-top:0!important}.mr-lg-0{margin-right:0!important}.mb-lg-0{margin-bottom:0!important}.ml-lg-0{margin-left:0!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.m-lg-1{margin:.25rem .25rem!important}.mt-lg-1{margin-top:.25rem!important}.mr-lg-1{margin-right:.25rem!important}.mb-lg-1{margin-bottom:.25rem!important}.ml-lg-1{margin-left:.25rem!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-lg-2{margin:.5rem .5rem!important}.mt-lg-2{margin-top:.5rem!important}.mr-lg-2{margin-right:.5rem!important}.mb-lg-2{margin-bottom:.5rem!important}.ml-lg-2{margin-left:.5rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-lg-3{margin:1rem 1rem!important}.mt-lg-3{margin-top:1rem!important}.mr-lg-3{margin-right:1rem!important}.mb-lg-3{margin-bottom:1rem!important}.ml-lg-3{margin-left:1rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-lg-4{margin:1.5rem 1.5rem!important}.mt-lg-4{margin-top:1.5rem!important}.mr-lg-4{margin-right:1.5rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.ml-lg-4{margin-left:1.5rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-lg-5{margin:3rem 3rem!important}.mt-lg-5{margin-top:3rem!important}.mr-lg-5{margin-right:3rem!important}.mb-lg-5{margin-bottom:3rem!important}.ml-lg-5{margin-left:3rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-lg-0{padding:0 0!important}.pt-lg-0{padding-top:0!important}.pr-lg-0{padding-right:0!important}.pb-lg-0{padding-bottom:0!important}.pl-lg-0{padding-left:0!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.p-lg-1{padding:.25rem .25rem!important}.pt-lg-1{padding-top:.25rem!important}.pr-lg-1{padding-right:.25rem!important}.pb-lg-1{padding-bottom:.25rem!important}.pl-lg-1{padding-left:.25rem!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-lg-2{padding:.5rem .5rem!important}.pt-lg-2{padding-top:.5rem!important}.pr-lg-2{padding-right:.5rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pl-lg-2{padding-left:.5rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-lg-3{padding:1rem 1rem!important}.pt-lg-3{padding-top:1rem!important}.pr-lg-3{padding-right:1rem!important}.pb-lg-3{padding-bottom:1rem!important}.pl-lg-3{padding-left:1rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-lg-4{padding:1.5rem 1.5rem!important}.pt-lg-4{padding-top:1.5rem!important}.pr-lg-4{padding-right:1.5rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pl-lg-4{padding-left:1.5rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-lg-5{padding:3rem 3rem!important}.pt-lg-5{padding-top:3rem!important}.pr-lg-5{padding-right:3rem!important}.pb-lg-5{padding-bottom:3rem!important}.pl-lg-5{padding-left:3rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto{margin-top:auto!important}.mr-lg-auto{margin-right:auto!important}.mb-lg-auto{margin-bottom:auto!important}.ml-lg-auto{margin-left:auto!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0 0!important}.mt-xl-0{margin-top:0!important}.mr-xl-0{margin-right:0!important}.mb-xl-0{margin-bottom:0!important}.ml-xl-0{margin-left:0!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.m-xl-1{margin:.25rem .25rem!important}.mt-xl-1{margin-top:.25rem!important}.mr-xl-1{margin-right:.25rem!important}.mb-xl-1{margin-bottom:.25rem!important}.ml-xl-1{margin-left:.25rem!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-xl-2{margin:.5rem .5rem!important}.mt-xl-2{margin-top:.5rem!important}.mr-xl-2{margin-right:.5rem!important}.mb-xl-2{margin-bottom:.5rem!important}.ml-xl-2{margin-left:.5rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-xl-3{margin:1rem 1rem!important}.mt-xl-3{margin-top:1rem!important}.mr-xl-3{margin-right:1rem!important}.mb-xl-3{margin-bottom:1rem!important}.ml-xl-3{margin-left:1rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.m-xl-4{margin:1.5rem 1.5rem!important}.mt-xl-4{margin-top:1.5rem!important}.mr-xl-4{margin-right:1.5rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.ml-xl-4{margin-left:1.5rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-xl-5{margin:3rem 3rem!important}.mt-xl-5{margin-top:3rem!important}.mr-xl-5{margin-right:3rem!important}.mb-xl-5{margin-bottom:3rem!important}.ml-xl-5{margin-left:3rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.p-xl-0{padding:0 0!important}.pt-xl-0{padding-top:0!important}.pr-xl-0{padding-right:0!important}.pb-xl-0{padding-bottom:0!important}.pl-xl-0{padding-left:0!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.p-xl-1{padding:.25rem .25rem!important}.pt-xl-1{padding-top:.25rem!important}.pr-xl-1{padding-right:.25rem!important}.pb-xl-1{padding-bottom:.25rem!important}.pl-xl-1{padding-left:.25rem!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-xl-2{padding:.5rem .5rem!important}.pt-xl-2{padding-top:.5rem!important}.pr-xl-2{padding-right:.5rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pl-xl-2{padding-left:.5rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-xl-3{padding:1rem 1rem!important}.pt-xl-3{padding-top:1rem!important}.pr-xl-3{padding-right:1rem!important}.pb-xl-3{padding-bottom:1rem!important}.pl-xl-3{padding-left:1rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.p-xl-4{padding:1.5rem 1.5rem!important}.pt-xl-4{padding-top:1.5rem!important}.pr-xl-4{padding-right:1.5rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pl-xl-4{padding-left:1.5rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-xl-5{padding:3rem 3rem!important}.pt-xl-5{padding-top:3rem!important}.pr-xl-5{padding-right:3rem!important}.pb-xl-5{padding-bottom:3rem!important}.pl-xl-5{padding-left:3rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto{margin-top:auto!important}.mr-xl-auto{margin-right:auto!important}.mb-xl-auto{margin-bottom:auto!important}.ml-xl-auto{margin-left:auto!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:700}.font-italic{font-style:italic}.text-white{color:#fff!important}.text-muted{color:#636c72!important}a.text-muted:focus,a.text-muted:hover{color:#4b5257!important}.text-primary{color:#0275d8!important}a.text-primary:focus,a.text-primary:hover{color:#025aa5!important}.text-success{color:#5cb85c!important}a.text-success:focus,a.text-success:hover{color:#449d44!important}.text-info{color:#5bc0de!important}a.text-info:focus,a.text-info:hover{color:#31b0d5!important}.text-warning{color:#f0ad4e!important}a.text-warning:focus,a.text-warning:hover{color:#ec971f!important}.text-danger{color:#d9534f!important}a.text-danger:focus,a.text-danger:hover{color:#c9302c!important}.text-gray-dark{color:#292b2c!important}a.text-gray-dark:focus,a.text-gray-dark:hover{color:#101112!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.invisible{visibility:hidden!important}.hidden-xs-up{display:none!important}@media (max-width:575px){.hidden-xs-down{display:none!important}}@media (min-width:576px){.hidden-sm-up{display:none!important}}@media (max-width:767px){.hidden-sm-down{display:none!important}}@media (min-width:768px){.hidden-md-up{display:none!important}}@media (max-width:991px){.hidden-md-down{display:none!important}}@media (min-width:992px){.hidden-lg-up{display:none!important}}@media (max-width:1199px){.hidden-lg-down{display:none!important}}@media (min-width:1200px){.hidden-xl-up{display:none!important}}.hidden-xl-down{display:none!important}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}/*# sourceMappingURL=bootstrap.min.css.map */\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader?{\"sourceMap\":false,\"importLoaders\":1}!./~/postcss-loader!./~/bootstrap/dist/css/bootstrap.min.css\n// module id = 142\n// module chunks = 2","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \"/* You can add global styles to this file, and also import other style files */\\r\\n\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader?{\"sourceMap\":false,\"importLoaders\":1}!./~/postcss-loader!./src/styles.css\n// module id = 143\n// module chunks = 2","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(self.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of + + + + +
+ + diff --git a/vaadin/pom.xml b/vaadin/pom.xml index e3786471f5..ea9a3ed75a 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -1,13 +1,12 @@ + 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"> 4.0.0 org.test vaadin 1.0-SNAPSHOT vaadin - war com.baeldung @@ -16,6 +15,11 @@ ../parent-boot-3 + + 17 + 24.3.3 + + @@ -30,39 +34,24 @@ - javax.servlet - javax.servlet-api - 4.0.1 - provided + com.vaadin + vaadin-core com.vaadin - vaadin-server - ${vaadin-server.version} - - - com.vaadin - vaadin-push - ${vaadin-push.version} - - - com.vaadin - vaadin-client-compiled - ${vaadin-client-compiled.version} - - - com.vaadin - vaadin-themes - ${vaadin-themes.version} + vaadin-spring-boot-starter org.springframework.boot spring-boot-starter-data-jpa - com.vaadin - vaadin-spring-boot-starter - ${vaadin-spring-boot-starter.version} + org.springframework.boot + spring-boot-starter-validation + + + io.projectreactor + reactor-core com.h2database @@ -77,47 +66,17 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** - - com.vaadin vaadin-maven-plugin - ${vaadin.plugin.version} - - - org.apache.maven.plugins - maven-clean-plugin - ${maven-clean-plugin.version} - - - - - src/main/webapp/VAADIN/themes - - **/styles.css - **/styles.scss.cache - - - - - - - - - org.eclipse.jetty - jetty-maven-plugin - ${jetty.plugin.version} - - 2 - + ${vaadin.version} + + + + prepare-frontend + + + org.springframework.boot @@ -126,68 +85,41 @@ - - - vaadin-addons - https://maven.vaadin.com/vaadin-addons - - - - vaadin-prerelease - - false - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - + + production + + + + com.vaadin + vaadin-core + + + com.vaadin + vaadin-dev + + + + + + + + com.vaadin + vaadin-maven-plugin + ${vaadin.version} + + + + build-frontend + + compile + + + + + - - - 13.0.9 - 13.0.9 - 13.0.9 - 8.8.5 - 8.8.5 - 8.8.5 - 8.8.5 - 9.3.9.v20160517 - local - mytheme - 3.0.0 - - \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java index 1d3084723a..b62dd79158 100644 --- a/vaadin/src/main/java/com/baeldung/Application.java +++ b/vaadin/src/main/java/com/baeldung/Application.java @@ -1,15 +1,19 @@ package com.baeldung; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; +import com.vaadin.flow.component.page.AppShellConfigurator; +import com.vaadin.flow.component.page.Push; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +@Push @SpringBootApplication -public class Application { +public class Application implements AppShellConfigurator { private static final Logger log = LoggerFactory.getLogger(Application.class); diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/EmployeeEditor.java deleted file mode 100644 index ee312786d1..0000000000 --- a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.baeldung; - -import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.KeyNotifier; -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.binder.Binder; -import com.vaadin.flow.spring.annotation.SpringComponent; -import com.vaadin.flow.spring.annotation.UIScope; -import org.springframework.beans.factory.annotation.Autowired; - -@SpringComponent -@UIScope -public class EmployeeEditor extends VerticalLayout implements KeyNotifier { - - private final EmployeeRepository repository; - - private Employee employee; - - TextField firstName = new TextField("First name"); - TextField lastName = new TextField("Last name"); - - Button save = new Button("Save", VaadinIcon.CHECK.create()); - Button cancel = new Button("Cancel"); - Button delete = new Button("Delete", VaadinIcon.TRASH.create()); - HorizontalLayout actions = new HorizontalLayout(save, cancel, delete); - - Binder binder = new Binder<>(Employee.class); - private ChangeHandler changeHandler; - - @Autowired - public EmployeeEditor(EmployeeRepository repository) { - this.repository = repository; - - add(firstName, lastName, actions); - - binder.bindInstanceFields(this); - - setSpacing(true); - - save.getElement().getThemeList().add("primary"); - delete.getElement().getThemeList().add("error"); - - addKeyPressListener(Key.ENTER, e -> save()); - - save.addClickListener(e -> save()); - delete.addClickListener(e -> delete()); - cancel.addClickListener(e -> editEmployee(employee)); - setVisible(false); - } - - void delete() { - repository.delete(employee); - changeHandler.onChange(); - } - - void save() { - repository.save(employee); - changeHandler.onChange(); - } - - public interface ChangeHandler { - void onChange(); - } - - public final void editEmployee(Employee c) { - if (c == null) { - setVisible(false); - return; - } - final boolean persisted = c.getId() != null; - if (persisted) { - employee = repository.findById(c.getId()).get(); - } else { - employee = c; - } - - cancel.setVisible(persisted); - binder.setBean(employee); - setVisible(true); - firstName.focus(); - } - - public void setChangeHandler(ChangeHandler h) { - changeHandler = h; - } -} diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java new file mode 100644 index 0000000000..45ab534ef6 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/IndexView.java @@ -0,0 +1,25 @@ +package com.baeldung; + +import com.baeldung.introduction.PushView; +import com.baeldung.introduction.basics.VaadinFlowBasics; +import com.baeldung.introduction.FormView; +import com.baeldung.introduction.GridView; +import com.baeldung.spring.EmployeesView; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +@Route("") +public class IndexView extends VerticalLayout { + + public IndexView() { + add(new H1("Vaadin Flow examples")); + + add(new RouterLink("Basics", VaadinFlowBasics.class)); + add(new RouterLink("Grid", GridView.class)); + add(new RouterLink("Form", FormView.class)); + add(new RouterLink("Push", PushView.class)); + add(new RouterLink("CRUD", EmployeesView.class)); + } +} diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/MainView.java deleted file mode 100644 index 6d4c0aaa88..0000000000 --- a/vaadin/src/main/java/com/baeldung/MainView.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.baeldung; - -import org.springframework.util.StringUtils; - -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.Route; - -@Route -public class MainView extends VerticalLayout { - - private final EmployeeRepository employeeRepository; - - private final EmployeeEditor editor; - - final Grid grid; - - final TextField filter; - - private final Button addNewBtn; - - public MainView(EmployeeRepository repo, EmployeeEditor editor) { - this.employeeRepository = repo; - this.editor = editor; - this.grid = new Grid<>(Employee.class); - this.filter = new TextField(); - this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create()); - - HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn); - add(actions, grid, editor); - - grid.setHeight("200px"); - grid.setColumns("id", "firstName", "lastName"); - grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0); - - filter.setPlaceholder("Filter by last name"); - - filter.setValueChangeMode(ValueChangeMode.EAGER); - filter.addValueChangeListener(e -> listEmployees(e.getValue())); - - grid.asSingleSelect().addValueChangeListener(e -> { - editor.editEmployee(e.getValue()); - }); - - addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", ""))); - - editor.setChangeHandler(() -> { - editor.setVisible(false); - listEmployees(filter.getValue()); - }); - - listEmployees(null); - } - - void listEmployees(String filterText) { - if (StringUtils.isEmpty(filterText)) { - grid.setItems(employeeRepository.findAll()); - } else { - grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText)); - } - } -} diff --git a/vaadin/src/main/java/com/baeldung/data/Contact.java b/vaadin/src/main/java/com/baeldung/data/Contact.java new file mode 100644 index 0000000000..8e534d5bb0 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/Contact.java @@ -0,0 +1,73 @@ +package com.baeldung.data; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; + +@Entity +public class Contact { + + @Id + @GeneratedValue + private Long id; + @NotBlank + private String name; + @Email + private String email; + @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}") + private String phone; + + public Contact() { + } + + public Contact(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "Contact {" + + "id=" + id + + ", name='" + name + "'" + + ", email='" + email + "'" + + ", phone='" + phone + "'" + + " }"; + } +} diff --git a/vaadin/src/main/java/com/baeldung/data/ContactRepository.java b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java new file mode 100644 index 0000000000..15c4adaaa9 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.data; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ContactRepository extends JpaRepository { +} diff --git a/vaadin/src/main/java/com/baeldung/data/DataInitializer.java b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java new file mode 100644 index 0000000000..dba162d4e4 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java @@ -0,0 +1,46 @@ +package com.baeldung.data; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@Component +public class DataInitializer implements CommandLineRunner { + + private final ContactRepository contactRepository; + + public DataInitializer(ContactRepository contactRepository) { + this.contactRepository = contactRepository; + } + + private final List firstNames = List.of( + "John", "Jane", "Emily", "Michael", "Sarah", "James", "Mary", "Robert", + "Patricia", "William", "Linda", "David", "Barbara", "Richard", "Susan", + "Joseph", "Jessica", "Thomas", "Karen", "Charles" + ); + private final List lastNames = List.of( + "Doe", "Smith", "Johnson", "Brown", "Davis", "Miller", "Wilson", "Moore", + "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", + "Thompson", "Garcia", "Martinez", "Robinson", "Clark" + ); + + @Override + public void run(String... args) throws Exception { + var contacts = new ArrayList(); + Random random = new Random(); + + for (int i = 0; i < 100; i++) { + String firstName = firstNames.get(random.nextInt(firstNames.size())); + String lastName = lastNames.get(random.nextInt(lastNames.size())); + String email = String.format("%s.%s@example.com", firstName.toLowerCase(), lastName.toLowerCase()); + String phone = String.format("555-%03d-%04d", random.nextInt(1000), random.nextInt(10000)); + + contacts.add(new Contact(firstName + " " + lastName, email, phone)); + } + + contactRepository.saveAll(contacts); + } +} diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java similarity index 75% rename from vaadin/src/main/java/com/baeldung/Employee.java rename to vaadin/src/main/java/com/baeldung/data/Employee.java index 75a0dc84b3..cdaa426eeb 100644 --- a/vaadin/src/main/java/com/baeldung/Employee.java +++ b/vaadin/src/main/java/com/baeldung/data/Employee.java @@ -1,8 +1,10 @@ -package com.baeldung; +package com.baeldung.data; + import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.validation.constraints.Size; @Entity public class Employee { @@ -11,11 +13,13 @@ public class Employee { @GeneratedValue private Long id; + @Size(min = 2, message = "First name must have at least 2 characters") private String firstName; + @Size(min = 2, message = "Last name must have at least 2 characters") private String lastName; - protected Employee() { + public Employee() { } public Employee(String firstName, String lastName) { @@ -27,6 +31,10 @@ public class Employee { return id; } + public void setId(Long id) { + this.id = id; + } + public String getFirstName() { return firstName; } diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java similarity index 89% rename from vaadin/src/main/java/com/baeldung/EmployeeRepository.java rename to vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java index 044160da78..0d54148c85 100644 --- a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java +++ b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.data; import java.util.List; diff --git a/vaadin/src/main/java/com/baeldung/introduction/BindData.java b/vaadin/src/main/java/com/baeldung/introduction/BindData.java deleted file mode 100644 index 299554c039..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/BindData.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.introduction; - -public class BindData { - - private String bindName; - - public BindData(String bindName){ - this.bindName = bindName; - } - - public String getBindName() { - return bindName; - } - - public void setBindName(String bindName) { - this.bindName = bindName; - } - - -} diff --git a/vaadin/src/main/java/com/baeldung/introduction/FormView.java b/vaadin/src/main/java/com/baeldung/introduction/FormView.java new file mode 100644 index 0000000000..34bc334b27 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/FormView.java @@ -0,0 +1,88 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.router.Route; + +@Route("form") +public class FormView extends HorizontalLayout { + + public FormView() { + addBeanValidationExample(); + addCustomValidationExample(); + } + + private void addBeanValidationExample() { + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new BeanValidationBinder<>(Contact.class); + + binder.forField(nameField).bind(Contact::getName, Contact::setName); + binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Bean Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } + + private void addCustomValidationExample() { + + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new Binder<>(Contact.class); + + binder.forField(nameField) + .asRequired() + .bind(Contact::getName, Contact::setName); + binder.forField(emailField) + .withValidator(email -> email.contains("@"), "Not a valid email address") + .bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField) + .withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number") + .bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Custom Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/GridView.java b/vaadin/src/main/java/com/baeldung/introduction/GridView.java new file mode 100644 index 0000000000..3d9500d7d8 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/GridView.java @@ -0,0 +1,40 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.baeldung.data.ContactRepository; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.data.VaadinSpringDataHelpers; + +@Route("grid") +public class GridView extends VerticalLayout { + + public GridView(ContactRepository contactRepository) { + + add(new H1("Using data grids")); + + // Define a grid for a Contact entity + var grid = new Grid(); + grid.addColumn(Contact::getName).setHeader("Name"); + grid.addColumn(Contact::getEmail).setHeader("Email"); + grid.addColumn(Contact::getPhone).setHeader("Phone"); + + // There are two ways to populate the grid with data: + + // 1) In-memory with a list of items + var contacts = contactRepository.findAll(); + grid.setItems(contacts); + + // 2) with a callback to lazily load items from a data source. + grid.setItems(query -> { + // Turn the page, offset, filter, sort and other info in query into a Spring Data PageRequest + var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query); + return contactRepository.findAll(pageRequest).stream(); + }); + + add(grid); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java new file mode 100644 index 0000000000..b49aa06e4d --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java @@ -0,0 +1,32 @@ +package com.baeldung.introduction; + +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import reactor.core.publisher.Flux; + +import java.time.Duration; +import java.time.Instant; + +// Ensure you have @Push annotation in your Application class +@Route("push") +public class PushView extends VerticalLayout { + + public PushView() { + var output = new Span(); + + // Publish server time once a second + var serverTime = Flux.interval(Duration.ofSeconds(1)) + .map(o -> "Server time: " + Instant.now()); + + + serverTime.subscribe(time -> + // ui.access is required to update the UI from a background thread + getUI().ifPresent(ui -> + ui.access(() -> output.setText(time)) + ) + ); + + add(output); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java deleted file mode 100644 index 412a286376..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/Row.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.introduction; - -public class Row { - - private String column1; - - private String column2; - - private String column3; - - public Row() { - - } - - public Row(String column1, String column2, String column3) { - super(); - this.column1 = column1; - this.column2 = column2; - this.column3 = column3; - } - - public String getColumn1() { - return column1; - } - - public void setColumn1(String column1) { - this.column1 = column1; - } - - public String getColumn2() { - return column2; - } - - public void setColumn2(String column2) { - this.column2 = column2; - } - - public String getColumn3() { - return column3; - } - - public void setColumn3(String column3) { - this.column3 = column3; - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java deleted file mode 100644 index 05a8340bde..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.baeldung.introduction; - -import java.time.Instant; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import com.vaadin.annotations.Push; -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.VaadinServletConfiguration; -import com.vaadin.data.Binder; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.icons.VaadinIcons; -import com.vaadin.server.ExternalResource; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinServlet; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Grid; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeButton; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PasswordField; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; -import com.vaadin.ui.TwinColSelect; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; -import jakarta.servlet.annotation.WebServlet; - -@SuppressWarnings("serial") -@Push -@Theme("mytheme") -public class VaadinUI extends UI { - - private Label currentTime; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void init(VaadinRequest vaadinRequest) { - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSpacing(true); - verticalLayout.setMargin(true); - final GridLayout gridLayout = new GridLayout(3, 2); - gridLayout.setSpacing(true); - gridLayout.setMargin(true); - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSpacing(true); - horizontalLayout.setMargin(true); - final FormLayout formLayout = new FormLayout(); - formLayout.setSpacing(true); - formLayout.setMargin(true); - final GridLayout buttonLayout = new GridLayout(3, 5); - buttonLayout.setMargin(true); - buttonLayout.setSpacing(true); - - final Label label = new Label(); - label.setId("Label"); - label.setValue("Label Value"); - label.setCaption("Label"); - gridLayout.addComponent(label); - - final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/")); - link.setId("Link"); - link.setTargetName("_blank"); - gridLayout.addComponent(link); - - final TextField textField = new TextField(); - textField.setId("TextField"); - textField.setCaption("TextField:"); - textField.setValue("TextField Value"); - textField.setIcon(VaadinIcons.USER); - gridLayout.addComponent(textField); - - final TextArea textArea = new TextArea(); - textArea.setCaption("TextArea"); - textArea.setId("TextArea"); - textArea.setValue("TextArea Value"); - gridLayout.addComponent(textArea); - - final DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0)); - dateField.setId("DateField"); - gridLayout.addComponent(dateField); - - final PasswordField passwordField = new PasswordField(); - passwordField.setId("PasswordField"); - passwordField.setCaption("PasswordField:"); - passwordField.setValue("password"); - gridLayout.addComponent(passwordField); - - final RichTextArea richTextArea = new RichTextArea(); - richTextArea.setCaption("Rich Text Area"); - richTextArea.setValue("

RichTextArea

"); - richTextArea.setSizeFull(); - - Panel richTextPanel = new Panel(); - richTextPanel.setContent(richTextArea); - - final InlineDateField inlineDateField = new InlineDateField(); - inlineDateField.setValue(LocalDate.ofEpochDay(0)); - inlineDateField.setCaption("Inline Date Field"); - horizontalLayout.addComponent(inlineDateField); - - Button normalButton = new Button("Normal Button"); - normalButton.setId("NormalButton"); - normalButton.addClickListener(e -> { - label.setValue("CLICK"); - }); - buttonLayout.addComponent(normalButton); - - Button tinyButton = new Button("Tiny Button"); - tinyButton.addStyleName("tiny"); - buttonLayout.addComponent(tinyButton); - - Button smallButton = new Button("Small Button"); - smallButton.addStyleName("small"); - buttonLayout.addComponent(smallButton); - - Button largeButton = new Button("Large Button"); - largeButton.addStyleName("large"); - buttonLayout.addComponent(largeButton); - - Button hugeButton = new Button("Huge Button"); - hugeButton.addStyleName("huge"); - buttonLayout.addComponent(hugeButton); - - Button disabledButton = new Button("Disabled Button"); - disabledButton.setDescription("This button cannot be clicked"); - disabledButton.setEnabled(false); - buttonLayout.addComponent(disabledButton); - - Button dangerButton = new Button("Danger Button"); - dangerButton.addStyleName("danger"); - buttonLayout.addComponent(dangerButton); - - Button friendlyButton = new Button("Friendly Button"); - friendlyButton.addStyleName("friendly"); - buttonLayout.addComponent(friendlyButton); - - Button primaryButton = new Button("Primary Button"); - primaryButton.addStyleName("primary"); - buttonLayout.addComponent(primaryButton); - - NativeButton nativeButton = new NativeButton("Native Button"); - buttonLayout.addComponent(nativeButton); - - Button iconButton = new Button("Icon Button"); - iconButton.setIcon(VaadinIcons.ALIGN_LEFT); - buttonLayout.addComponent(iconButton); - - Button borderlessButton = new Button("BorderLess Button"); - borderlessButton.addStyleName("borderless"); - buttonLayout.addComponent(borderlessButton); - - Button linkButton = new Button("Link Button"); - linkButton.addStyleName("link"); - buttonLayout.addComponent(linkButton); - - Button quietButton = new Button("Quiet Button"); - quietButton.addStyleName("quiet"); - buttonLayout.addComponent(quietButton); - - horizontalLayout.addComponent(buttonLayout); - - final CheckBox checkbox = new CheckBox("CheckBox"); - checkbox.setValue(true); - checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue())); - formLayout.addComponent(checkbox); - - List numbers = new ArrayList(); - numbers.add("One"); - numbers.add("Ten"); - numbers.add("Eleven"); - ComboBox comboBox = new ComboBox("ComboBox"); - comboBox.setItems(numbers); - formLayout.addComponent(comboBox); - - ListSelect listSelect = new ListSelect("ListSelect"); - listSelect.setItems(numbers); - listSelect.setRows(2); - formLayout.addComponent(listSelect); - - NativeSelect nativeSelect = new NativeSelect("NativeSelect"); - nativeSelect.setItems(numbers); - formLayout.addComponent(nativeSelect); - - TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); - twinColSelect.setItems(numbers); - - Grid grid = new Grid(Row.class); - grid.setColumns("column1", "column2", "column3"); - Row row1 = new Row("Item1", "Item2", "Item3"); - Row row2 = new Row("Item4", "Item5", "Item6"); - List rows = new ArrayList(); - rows.add(row1); - rows.add(row2); - grid.setItems(rows); - - Panel panel = new Panel("Panel"); - panel.setContent(grid); - panel.setSizeUndefined(); - - Panel serverPushPanel = new Panel("Server Push"); - FormLayout timeLayout = new FormLayout(); - timeLayout.setSpacing(true); - timeLayout.setMargin(true); - currentTime = new Label("No TIME..."); - timeLayout.addComponent(currentTime); - serverPushPanel.setContent(timeLayout); - serverPushPanel.setSizeUndefined(); - ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1); - Runnable task = () -> { - currentTime.setValue("Current Time : " + Instant.now()); - }; - scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); - - FormLayout dataBindingLayout = new FormLayout(); - dataBindingLayout.setSpacing(true); - dataBindingLayout.setMargin(true); - - Binder binder = new Binder<>(); - BindData bindData = new BindData("BindData"); - binder.readBean(bindData); - TextField bindedTextField = new TextField(); - bindedTextField.setWidth("250px"); - binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName); - dataBindingLayout.addComponent(bindedTextField); - - FormLayout validatorLayout = new FormLayout(); - validatorLayout.setSpacing(true); - validatorLayout.setMargin(true); - - HorizontalLayout textValidatorLayout = new HorizontalLayout(); - textValidatorLayout.setSpacing(true); - textValidatorLayout.setMargin(true); - - - BindData stringValidatorBindData = new BindData(""); - TextField stringValidator = new TextField(); - Binder stringValidatorBinder = new Binder<>(); - stringValidatorBinder.setBean(stringValidatorBindData); - stringValidatorBinder.forField(stringValidator) - .withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5)) - .bind(BindData::getBindName, BindData::setBindName); - - textValidatorLayout.addComponent(stringValidator); - Button buttonStringValidator = new Button("Validate String"); - buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate()); - textValidatorLayout.addComponent(buttonStringValidator); - - validatorLayout.addComponent(textValidatorLayout); - verticalLayout.addComponent(gridLayout); - verticalLayout.addComponent(richTextPanel); - verticalLayout.addComponent(horizontalLayout); - verticalLayout.addComponent(formLayout); - verticalLayout.addComponent(twinColSelect); - verticalLayout.addComponent(panel); - verticalLayout.addComponent(serverPushPanel); - verticalLayout.addComponent(dataBindingLayout); - verticalLayout.addComponent(validatorLayout); - setContent(verticalLayout); - } - - @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java new file mode 100644 index 0000000000..6d6e2b2b7d --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java @@ -0,0 +1,45 @@ +package com.baeldung.introduction.basics; + +import com.baeldung.data.Contact; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.splitlayout.SplitLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; + +import java.util.List; + +@Route("example-layout") +public class ExampleLayout extends SplitLayout { + + public ExampleLayout() { + var grid = new Grid<>(Contact.class); + grid.setColumns("name", "email", "phone"); + grid.setItems(List.of( + new Contact("John Doe", "john@doe.com", "123 456 789"), + new Contact("Jane Doe", "jane@doe.com", "987 654 321") + )); + + var form = new VerticalLayout(); + + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + var cancelButton = new Button("Cancel"); + + form.add( + nameField, + emailField, + phoneField, + new HorizontalLayout(saveButton, cancelButton) + ); + + setSizeFull(); + setSplitterPosition(70); + addToPrimary(grid); + addToSecondary(form); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java new file mode 100644 index 0000000000..477cf378c6 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java @@ -0,0 +1,13 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; + +@Route("hello-world") +public class HelloWorldView extends VerticalLayout { + + public HelloWorldView() { + add(new H1("Hello, World!")); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java new file mode 100644 index 0000000000..7a22eea0ab --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java @@ -0,0 +1,63 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +// The @Route annotation defines the URL path for the view +// Any component, most commonly a layout, can be used as a view +@Route("basics") +public class VaadinFlowBasics extends VerticalLayout { + public VaadinFlowBasics() { + + // Add components to the layout with the add method + add(new H1("Vaadin Flow Basics")); + + // Components are Java objects + var textField = new TextField("Name"); + var button = new Button("Click me"); + + // Layouts define the structure of the UI + var verticalLayout = new VerticalLayout( + new Button("Top"), + new Button("Middle"), + new Button("Bottom") + ); + add(verticalLayout); + + var horizontalLayout = new HorizontalLayout( + new Button("Left"), + new Button("Center"), + new Button("Right") + ); + add(horizontalLayout); + + // Layouts can be nested for more complex structures + var nestedLayout = new VerticalLayout( + new HorizontalLayout(new Button("Top Left"), new Button("Top Right")), + new HorizontalLayout(new Button("Bottom Left"), new Button("Bottom Right")) + ); + add(nestedLayout); + + add(new RouterLink("Example layout", ExampleLayout.class)); + + // Use RouterLink to navigate to other views + var link = new RouterLink("Hello world view", HelloWorldView.class); + add(link); + + // Use events to react to user input + var nameField = new TextField("Your name"); + var helloButton = new Button("Say hello"); + helloButton.addClickListener(e -> { + Notification.show("Hello, " + nameField.getValue()); + }); + add(nameField, helloButton); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java new file mode 100644 index 0000000000..7984ecce05 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java @@ -0,0 +1,86 @@ +package com.baeldung.spring; + +import com.baeldung.data.Employee; +import com.vaadin.flow.component.Composite; +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; + +public class EmployeeEditor extends Composite { + + public interface SaveListener { + void onSave(Employee employee); + } + + public interface DeleteListener { + void onDelete(Employee employee); + } + + public interface CancelListener { + void onCancel(); + } + + private Employee employee; + + private SaveListener saveListener; + private DeleteListener deleteListener; + private CancelListener cancelListener; + + private final Binder binder = new BeanValidationBinder<>(Employee.class); + +public EmployeeEditor() { + var firstName = new TextField("First name"); + var lastName = new TextField("Last name"); + + var save = new Button("Save", VaadinIcon.CHECK.create()); + var cancel = new Button("Cancel"); + var delete = new Button("Delete", VaadinIcon.TRASH.create()); + + binder.forField(firstName).bind("firstName"); + binder.forField(lastName).bind("lastName"); + + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + save.addClickListener(e -> save()); + save.addClickShortcut(Key.ENTER); + + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + delete.addClickListener(e -> deleteListener.onDelete(employee)); + + cancel.addClickListener(e -> cancelListener.onCancel()); + + getContent().add(firstName, lastName, new HorizontalLayout(save, cancel, delete)); +} + + private void save() { + // Save the form into a new instance of Employee + var updated = new Employee(); + updated.setId(employee.getId()); + + if (binder.writeBeanIfValid(updated)) { + saveListener.onSave(updated); + } + } + + public void setEmployee(Employee employee) { + this.employee = employee; + binder.readBean(employee); + } + + public void setSaveListener(SaveListener saveListener) { + this.saveListener = saveListener; + } + + public void setDeleteListener(DeleteListener deleteListener) { + this.deleteListener = deleteListener; + } + + public void setCancelListener(CancelListener cancelListener) { + this.cancelListener = cancelListener; + } +} diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java new file mode 100644 index 0000000000..edb1f7a75b --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java @@ -0,0 +1,95 @@ +package com.baeldung.spring; + +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.Route; + +@Route("employees") +public class EmployeesView extends VerticalLayout { + + private final EmployeeRepository employeeRepository; + + private final TextField filter; + private final Grid grid; + private final EmployeeEditor editor; + + + public EmployeesView(EmployeeRepository repo) { + employeeRepository = repo; + + // Create components + var addButton = new Button("New employee", VaadinIcon.PLUS.create()); + filter = new TextField(); + grid = new Grid<>(Employee.class); + editor = new EmployeeEditor(); + + // Configure components + configureEditor(); + + addButton.addClickListener(e -> editEmployee(new Employee())); + + filter.setPlaceholder("Filter by last name"); + filter.setValueChangeMode(ValueChangeMode.LAZY); + filter.addValueChangeListener(e -> updateEmployees(e.getValue())); + + grid.setHeight("200px"); + grid.asSingleSelect().addValueChangeListener(e -> editEmployee(e.getValue())); + + // Compose layout + var actionsLayout = new HorizontalLayout(filter, addButton); + add(actionsLayout, grid, editor); + + // List customers + updateEmployees(""); + } + + private void configureEditor() { + editor.setVisible(false); + + editor.setSaveListener(employee -> { + var saved = employeeRepository.save(employee); + updateEmployees(filter.getValue()); + editor.setEmployee(null); + grid.asSingleSelect().setValue(saved); + }); + + editor.setDeleteListener(employee -> { + employeeRepository.delete(employee); + updateEmployees(filter.getValue()); + editEmployee(null); + }); + + editor.setCancelListener(() -> { + editEmployee(null); + }); + } + + private void editEmployee(Employee employee) { + editor.setEmployee(employee); + + if (employee != null) { + editor.setVisible(true); + } else { + // Deselect grid + grid.asSingleSelect().setValue(null); + editor.setVisible(false); + } + + } + + private void updateEmployees(String filterText) { + if (filterText.isEmpty()) { + grid.setItems(employeeRepository.findAll()); + } else { + grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText)); + } + } +} diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss deleted file mode 100644 index a5670b70c7..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss +++ /dev/null @@ -1,7 +0,0 @@ -/* This file is automatically managed and will be overwritten from time to time. */ -/* Do not manually edit this file. */ - -/* Import and include this mixin into your project theme to include the addon themes */ -@mixin addons { -} - diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico deleted file mode 100644 index ffb34a65c7..0000000000 Binary files a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico and /dev/null differ diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss deleted file mode 100644 index 2c5fb8b944..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss +++ /dev/null @@ -1,38 +0,0 @@ -// If you edit this file you need to compile the theme. See README.md for details. - -// Global variable overrides. Must be declared before importing Valo. - -// Defines the plaintext font size, weight and family. Font size affects general component sizing. -//$v-font-size: 16px; -//$v-font-weight: 300; -//$v-font-family: "Open Sans", sans-serif; - -// Defines the border used by all components. -//$v-border: 1px solid (v-shade 0.7); -//$v-border-radius: 4px; - -// Affects the color of some component elements, e.g Button, Panel title, etc -//$v-background-color: hsl(210, 0%, 98%); -// Affects the color of content areas, e.g Panel and Window content, TextField input etc -//$v-app-background-color: $v-background-color; - -// Affects the visual appearance of all components -//$v-gradient: v-linear 8%; -//$v-bevel-depth: 30%; -//$v-shadow-opacity: 5%; - -// Defines colors for indicating status (focus, success, failure) -//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically -//$v-friendly-color: #2c9720; -//$v-error-indicator-color: #ed473b; - -// For more information, see: https://vaadin.com/book/-/page/themes.valo.html -// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples - -@import "../valo/valo.scss"; - -@mixin mytheme { - @include valo; - - // Insert your own theme rules here -} diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss deleted file mode 100644 index bba1d493c0..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import "mytheme.scss"; -@import "addons.scss"; - -// This file prefixes all rules with the theme name to avoid causing conflicts with other themes. -// The actual styles should be defined in mytheme.scss - -.mytheme { - @include addons; - @include mytheme; - -} diff --git a/web-modules/jakarta-ee/pom.xml b/web-modules/jakarta-ee/pom.xml index faad33338b..4caa67bf6f 100644 --- a/web-modules/jakarta-ee/pom.xml +++ b/web-modules/jakarta-ee/pom.xml @@ -48,7 +48,7 @@ org.mockito - mockito-all + mockito-core ${mockito.version} test @@ -100,11 +100,10 @@ 9.0.0 2.0.0 2.0.0 - 5.8.2 + 5.10.2 C:/glassfish6 admin mvn-domain - 1.10.19 ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords diff --git a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java index 5e79924ed7..a116db3c65 100644 --- a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java +++ b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java @@ -1,25 +1,23 @@ package com.baeldung.eclipse.krazo; -import com.baeldung.eclipse.krazo.User; -import com.baeldung.eclipse.krazo.UserController; -import jakarta.mvc.Models; -import jakarta.mvc.binding.BindingResult; -import org.eclipse.krazo.core.ModelsImpl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; +import org.eclipse.krazo.core.ModelsImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import jakarta.mvc.Models; +import jakarta.mvc.binding.BindingResult; + /** * The class contains unit tests. We do only unit tests. Most of the classes are mocked */ diff --git a/web-modules/javax-servlets-2/pom.xml b/web-modules/javax-servlets-2/pom.xml index a792f6eea2..8031786af4 100644 --- a/web-modules/javax-servlets-2/pom.xml +++ b/web-modules/javax-servlets-2/pom.xml @@ -112,7 +112,6 @@ 2.22.2 10.0.4 1.10.0 - 5.6.0 1.5.4
diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml index b26027d9bf..9bbfc33e62 100644 --- a/web-modules/jee-7/pom.xml +++ b/web-modules/jee-7/pom.xml @@ -16,6 +16,13 @@ 1.0.0-SNAPSHOT + + + jboss-https + https://repository.jboss.org/nexus/content/groups/public/ + + + @@ -305,7 +312,7 @@ test - org.wildfly + org.wildfly.arquillian wildfly-arquillian-container-managed ${wildfly.version} test @@ -338,7 +345,7 @@ org.wildfly wildfly-dist - ${wildfly.version} + ${wildfly-dist.version} zip false ${project.build.directory} @@ -388,7 +395,7 @@ test - org.wildfly + org.wildfly.arquillian wildfly-arquillian-container-remote ${wildfly.version} test @@ -513,7 +520,8 @@ 3.0.0 7.0 1.1.11.Final - 8.2.1.Final + 31.0.1.Final + 5.0.1.Final 1.7.0 1.4.6.Final 3.0.19.Final diff --git a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java index e753d34901..e87bd100c8 100644 --- a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java +++ b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java @@ -5,6 +5,7 @@ import com.baeldung.jersey.server.config.HelloBinding; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Response; @Path("/greetings") @@ -17,6 +18,7 @@ public class Greetings { } @GET + @Produces("text/html") @Path("/hi") public String getHiGreeting() { return "hi"; diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java index 47736f90d7..e01415b50a 100644 --- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java +++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java @@ -1,18 +1,18 @@ package com.baeldung.jersey.server; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -public class GreetingsResourceIntegrationTest extends JerseyTest { +class GreetingsResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { @@ -21,14 +21,14 @@ public class GreetingsResourceIntegrationTest extends JerseyTest { } @Test - public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { + void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { Response response = target("/greetings/hi").request() .get(); - assertEquals("Http Response should be 200: ", Response.Status.OK.getStatusCode(), response.getStatus()); - assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals(MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); String content = response.readEntity(String.class); - assertEquals("Content of ressponse is: ", "hi", content); + assertEquals("hi", content); } } diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java index 4f73c9df5b..2eaeb94a00 100644 --- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java +++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java @@ -2,12 +2,12 @@ package com.baeldung.jersey.server.rest; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.baeldung.jersey.server.config.ViewApplicationConfig; import com.baeldung.jersey.server.model.Fruit; @@ -19,7 +19,7 @@ import jakarta.ws.rs.core.Form; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -public class FruitResourceIntegrationTest extends JerseyTest { +class FruitResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { @@ -33,80 +33,80 @@ public class FruitResourceIntegrationTest extends JerseyTest { } @Test - public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { + void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { final String response = target("/fruit/all").request() .get(String.class); assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi"))); } @Test - public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { + void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { final String response = target("/fruit").request() .get(String.class); assertThat(response, containsString("Welcome Fruit Index Page!")); } @Test - public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { + void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { final String response = target("/fruit/orange").request() .get(String.class); assertThat(response, containsString("Error - Fruit not found: orange!")); } @Test - public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { + void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("name", "apple"); form.param("colour", null); Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED) .post(Entity.form(form)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null")); } @Test - public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { + void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { Response response = target("fruit/created").request() .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}")); - assertEquals("Http Response should be 201 ", Response.Status.CREATED.getStatusCode(), response.getStatus()); + assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]")); } @Test - public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { + void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("serial", "2345-2345"); Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED) .put(Entity.form(form)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid")); } @Test - public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { + void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { Fruit fruit = new Fruit("Blueberry", "purple"); fruit.setWeight(1); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater")); } @Test - public void givenFruitExists_whenSearching_thenResponseContainsFruit() { + void givenFruitExists_whenSearching_thenResponseContainsFruit() { Fruit fruit = new Fruit(); fruit.setName("strawberry"); fruit.setWeight(20); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 204 ", 204, response.getStatus()); + assertEquals(204, response.getStatus()); final String json = target("fruit/search/strawberry").request() .get(String.class); @@ -114,28 +114,28 @@ public class FruitResourceIntegrationTest extends JerseyTest { } @Test - public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { + void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { Fruit fruit = new Fruit(); fruit.setName("strawberry"); fruit.setWeight(20); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 204 ", 204, response.getStatus()); + assertEquals(204, response.getStatus()); final Fruit entity = target("fruit/search/strawberry").request() .get(Fruit.class); - assertEquals("Fruit name: ", "strawberry", entity.getName()); - assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight()); + assertEquals("strawberry", entity.getName()); + assertEquals(Integer.valueOf(20), entity.getWeight()); } @Test - public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { + void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { final Response response = target("fruit/exception").request() .get(); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); String responseString = response.readEntity(String.class); assertThat(responseString, containsString("exception..colour size must be between 5 and 200")); assertThat(responseString, containsString("exception..name size must be between 5 and 200")); diff --git a/web-modules/ratpack/pom.xml b/web-modules/ratpack/pom.xml index 3f93f25bef..c392788068 100644 --- a/web-modules/ratpack/pom.xml +++ b/web-modules/ratpack/pom.xml @@ -106,6 +106,8 @@ 1.5.12 2.4.15 1.6.1 + 1.7.32 + 1.2.7 \ No newline at end of file diff --git a/xml-2/README.md b/xml-2/README.md index 1075f34e1f..6040137dc1 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -11,4 +11,5 @@ This module contains articles about eXtensible Markup Language (XML) - [Convert String Containing XML to org.w3c.dom.Document](https://www.baeldung.com/java-convert-string-xml-dom) - [How to Parse XML to HashMap in Java](https://www.baeldung.com/java-xml-read-into-hashmap) - [Convert an XML File to CSV File](https://www.baeldung.com/java-convert-xml-csv) -- - More articles: [[prev -->]](../xml) \ No newline at end of file +- [Invalid Characters in XML](https://www.baeldung.com/java-xml-invalid-characters) +- - More articles: [[prev -->]](../xml) diff --git a/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java new file mode 100644 index 0000000000..7878e72f97 --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.xml.invalidcharacters; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXParseException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class InvalidCharactersUnitTest { + + @Test + void givenXml_whenReservedCharacters_thenThrowException() { + String invalidXmlString = "John & Doe"; + assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString)); + } + + @Test + void givenXml_whenReservedCharactersEscaped_thenSuccess() { + String validXmlString = "John & Doe"; + + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } + + @Test + void givenXml_whenUsingCdataForReservedCharacters_thenSuccess() { + String validXmlString = ""; + + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } + + @Test + void givenXml_whenUnicodeCharacters_thenThrowException() { + String invalidXmlString = "John \u001E Doe"; + assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString)); + } + + @Test + void givenXml_whenUnicodeCharactersEscaped_thenSuccess() { + String validXmlString = "John  Doe"; + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John \u001E Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } + + private Document parseXmlString(String xmlString) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource inputSource = new InputSource(new StringReader(xmlString)); + return builder.parse(inputSource); + } +}