Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-12800
This commit is contained in:
commit
567fcc1ba0
|
@ -15,3 +15,5 @@
|
||||||
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
||||||
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
||||||
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
||||||
|
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
|
||||||
|
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
|
||||||
|
|
|
@ -4,4 +4,3 @@
|
||||||
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
||||||
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
|
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
|
||||||
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
|
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
|
||||||
- [An Introduction to the Theory of Big-O Notation](http://www.baeldung.com/big-o-notation)
|
|
|
@ -3,5 +3,5 @@
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [String Matching in Groovy](http://www.baeldung.com/)
|
- [String Matching in Groovy](http://www.baeldung.com/)
|
||||||
- [Groovy def Keyword]
|
- [Groovy def Keyword](https://www.baeldung.com/groovy-def-keyword)
|
||||||
|
- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Dear <% out << (user) %>,
|
||||||
|
Please read the requested article below.
|
||||||
|
<% out << (articleText) %>
|
||||||
|
From,
|
||||||
|
<% out << (signature) %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
Dear $user,
|
||||||
|
Thanks for subscribing our services.
|
||||||
|
${signature}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.baeldung.templateengine
|
||||||
|
|
||||||
|
import groovy.text.SimpleTemplateEngine
|
||||||
|
import groovy.text.StreamingTemplateEngine
|
||||||
|
import groovy.text.GStringTemplateEngine
|
||||||
|
import groovy.text.XmlTemplateEngine
|
||||||
|
import groovy.text.XmlTemplateEngine
|
||||||
|
import groovy.text.markup.MarkupTemplateEngine
|
||||||
|
import groovy.text.markup.TemplateConfiguration
|
||||||
|
|
||||||
|
class TemplateEnginesUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
def bindMap = [user: "Norman", signature: "Baeldung"]
|
||||||
|
|
||||||
|
void testSimpleTemplateEngine() {
|
||||||
|
def smsTemplate = 'Dear <% print user %>, Thanks for reading our Article. ${signature}'
|
||||||
|
def smsText = new SimpleTemplateEngine().createTemplate(smsTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert smsText.toString() == "Dear Norman, Thanks for reading our Article. Baeldung"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStreamingTemplateEngine() {
|
||||||
|
def articleEmailTemplate = new File('src/main/resources/articleEmail.template')
|
||||||
|
bindMap.articleText = """1. Overview
|
||||||
|
This is a tutorial article on Template Engines""" //can be a string larger than 64k
|
||||||
|
|
||||||
|
def articleEmailText = new StreamingTemplateEngine().createTemplate(articleEmailTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert articleEmailText.toString() == """Dear Norman,
|
||||||
|
Please read the requested article below.
|
||||||
|
1. Overview
|
||||||
|
This is a tutorial article on Template Engines
|
||||||
|
From,
|
||||||
|
Baeldung"""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testGStringTemplateEngine() {
|
||||||
|
def emailTemplate = new File('src/main/resources/email.template')
|
||||||
|
def emailText = new GStringTemplateEngine().createTemplate(emailTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert emailText.toString() == "Dear Norman,\nThanks for subscribing our services.\nBaeldung"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testXmlTemplateEngine() {
|
||||||
|
def emailXmlTemplate = '''<xs xmlns:gsp='groovy-server-pages'>
|
||||||
|
<gsp:scriptlet>def emailContent = "Thanks for subscribing our services."</gsp:scriptlet>
|
||||||
|
<email>
|
||||||
|
<greet>Dear ${user}</greet>
|
||||||
|
<content><gsp:expression>emailContent</gsp:expression></content>
|
||||||
|
<signature>${signature}</signature>
|
||||||
|
</email>
|
||||||
|
</xs>'''
|
||||||
|
def emailXml = new XmlTemplateEngine().createTemplate(emailXmlTemplate).make(bindMap)
|
||||||
|
println emailXml.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMarkupTemplateEngineHtml() {
|
||||||
|
def emailHtmlTemplate = """html {
|
||||||
|
head {
|
||||||
|
title('Service Subscription Email')
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
p('Dear Norman')
|
||||||
|
p('Thanks for subscribing our services.')
|
||||||
|
p('Baeldung')
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
|
||||||
|
def emailHtml = new MarkupTemplateEngine().createTemplate(emailHtmlTemplate).make()
|
||||||
|
println emailHtml.toString()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMarkupTemplateEngineXml() {
|
||||||
|
def emailXmlTemplate = """xmlDeclaration()
|
||||||
|
xs{
|
||||||
|
email {
|
||||||
|
greet('Dear Norman')
|
||||||
|
content('Thanks for subscribing our services.')
|
||||||
|
signature('Baeldung')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
TemplateConfiguration config = new TemplateConfiguration()
|
||||||
|
config.autoIndent = true
|
||||||
|
config.autoEscape = true
|
||||||
|
config.autoNewLine = true
|
||||||
|
|
||||||
|
def emailXml = new MarkupTemplateEngine(config).createTemplate(emailXmlTemplate).make()
|
||||||
|
|
||||||
|
println emailXml.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
- [Maps in Groovy](http://www.baeldung.com/)
|
- [Maps in Groovy](https://www.baeldung.com/groovy-maps)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant Articles
|
||||||
|
|
||||||
|
- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end)
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.array.conversions;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.IntFunction;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class StreamArrayConversion {
|
||||||
|
|
||||||
|
public static String[] stringStreamToStringArrayUsingFunctionalInterface(Stream<String> stringStream) {
|
||||||
|
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
|
||||||
|
@Override
|
||||||
|
public String[] apply(int value) {
|
||||||
|
return new String[value];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return stringStream.toArray(intFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] stringStreamToStringArrayUsingMethodReference(Stream<String> stringStream) {
|
||||||
|
return stringStream.toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] stringStreamToStringArrayUsingLambda(Stream<String> stringStream) {
|
||||||
|
return stringStream.toArray(value -> new String[value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[] integerStreamToIntegerArray(Stream<Integer> integerStream) {
|
||||||
|
return integerStream.toArray(Integer[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] intStreamToPrimitiveIntArray(Stream<Integer> integerStream) {
|
||||||
|
return integerStream.mapToInt(i -> i).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<String> stringArrayToStreamUsingArraysStream(String[] stringArray) {
|
||||||
|
return Arrays.stream(stringArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<String> stringArrayToStreamUsingStreamOf(String[] stringArray) {
|
||||||
|
return Stream.of(stringArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntStream primitiveIntArrayToStreamUsingArraysStream(int[] intArray) {
|
||||||
|
return Arrays.stream(intArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<int[]> primitiveIntArrayToStreamUsingStreamOf(int[] intArray) {
|
||||||
|
return Stream.of(intArray);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.array.conversions;
|
||||||
|
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.intStreamToPrimitiveIntArray;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.integerStreamToIntegerArray;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingFunctionalInterface;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingLambda;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingMethodReference;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.stringArrayToStreamUsingArraysStream;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.stringArrayToStreamUsingStreamOf;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.primitiveIntArrayToStreamUsingArraysStream;
|
||||||
|
import static com.baeldung.array.conversions.StreamArrayConversion.primitiveIntArrayToStreamUsingStreamOf;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class StreamArrayConversionUnitTest {
|
||||||
|
|
||||||
|
private String[] stringArray = new String[]{"baeldung", "convert", "to", "string", "array"};
|
||||||
|
private Integer[] integerArray = new Integer[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
private int[] intPrimitiveArray = new int[]{1, 2, 3, 4, 5, 6, 7};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStringStream_thenConvertToStringArrayUsingFunctionalInterface() {
|
||||||
|
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||||
|
assertArrayEquals(stringArray, stringStreamToStringArrayUsingFunctionalInterface(stringStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStringStream_thenConvertToStringArrayUsingMethodReference() {
|
||||||
|
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||||
|
assertArrayEquals(stringArray, stringStreamToStringArrayUsingMethodReference(stringStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStringStream_thenConvertToStringArrayUsingLambda() {
|
||||||
|
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||||
|
assertArrayEquals(stringArray, stringStreamToStringArrayUsingLambda(stringStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenIntegerStream_thenConvertToIntegerArray() {
|
||||||
|
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
assertArrayEquals(integerArray, integerStreamToIntegerArray(integerStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenIntStream_thenConvertToIntegerArray() {
|
||||||
|
Stream<Integer> integerStream = IntStream.rangeClosed(1, 7).boxed();
|
||||||
|
assertArrayEquals(intPrimitiveArray, intStreamToPrimitiveIntArray(integerStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStringArray_whenConvertedTwoWays_thenConvertedStreamsAreEqual() {
|
||||||
|
assertTrue(Iterators
|
||||||
|
.elementsEqual(stringArrayToStreamUsingArraysStream(stringArray).iterator(),
|
||||||
|
stringArrayToStreamUsingStreamOf(stringArray).iterator()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPrimitiveArray_whenConvertedTwoWays_thenConvertedStreamsAreNotEqual() {
|
||||||
|
assertFalse(Iterators.elementsEqual(
|
||||||
|
primitiveIntArrayToStreamUsingArraysStream(intPrimitiveArray).iterator(),
|
||||||
|
primitiveIntArrayToStreamUsingStreamOf(intPrimitiveArray).iterator()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-lambda-effectively-final-local-variables)
|
|
@ -7,3 +7,4 @@
|
||||||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||||
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||||
- [Guide to jlink](https://www.baeldung.com/jlink)
|
- [Guide to jlink](https://www.baeldung.com/jlink)
|
||||||
|
- [Transforming an Empty String into an Empty Optional](https://www.baeldung.com/java-empty-string-to-empty-optional)
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.string;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class StringAPITest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPositiveArgument_thenReturnIndentedString() {
|
||||||
|
String multilineStr = "This is\na multiline\nstring.";
|
||||||
|
String outputStr = " This is\n a multiline\n string.\n";
|
||||||
|
|
||||||
|
String postIndent = multilineStr.indent(3);
|
||||||
|
|
||||||
|
assertThat(postIndent, equalTo(outputStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNegativeArgument_thenReturnReducedIndentedString() {
|
||||||
|
String multilineStr = " This is\n a multiline\n string.";
|
||||||
|
String outputStr = " This is\n a multiline\n string.\n";
|
||||||
|
|
||||||
|
String postIndent = multilineStr.indent(-2);
|
||||||
|
|
||||||
|
assertThat(postIndent, equalTo(outputStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTransformUsingLamda_thenReturnTransformedString() {
|
||||||
|
String result = "hello".transform(input -> input + " world!");
|
||||||
|
|
||||||
|
assertThat(result, equalTo("hello world!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenTransformUsingParseInt_thenReturnInt() {
|
||||||
|
int result = "42".transform(Integer::parseInt);
|
||||||
|
|
||||||
|
assertThat(result, equalTo(42));
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,4 +3,5 @@
|
||||||
## Core Java 8 Cookbooks and Examples (part 2)
|
## Core Java 8 Cookbooks and Examples (part 2)
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Anonymous Classes in Java](http://www.baeldung.com/)
|
- [Anonymous Classes in Java](https://www.baeldung.com/java-anonymous-classes)
|
||||||
|
- [Run JAR Application With Command Line Arguments](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class OptionalChainingUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> createOptional(String input) {
|
private Optional<String> createOptional(String input) {
|
||||||
if (input == null || input == "" || input == "empty") {
|
if (input == null || "".equals(input) || "empty".equals(input)) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,14 @@
|
||||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||||
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||||
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
|
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
|
||||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new)
|
||||||
|
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
|
||||||
|
- [Java 9 Optional API Additions](https://www.baeldung.com/java-9-optional)
|
||||||
|
- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture)
|
||||||
|
- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api)
|
||||||
|
- [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods)
|
||||||
|
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
||||||
|
- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity)
|
||||||
|
- [Java 9 Platform Module API](https://www.baeldung.com/java-9-module-api)
|
||||||
|
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||||
|
- [Filtering a Stream of Optionals in Java](https://www.baeldung.com/java-filter-stream-of-optional)
|
||||||
|
|
|
@ -8,4 +8,5 @@
|
||||||
- [A Guide to HashSet in Java](http://www.baeldung.com/java-hashset)
|
- [A Guide to HashSet in Java](http://www.baeldung.com/java-hashset)
|
||||||
- [A Guide to TreeSet in Java](http://www.baeldung.com/java-tree-set)
|
- [A Guide to TreeSet in Java](http://www.baeldung.com/java-tree-set)
|
||||||
- [Initializing HashSet at the Time of Construction](http://www.baeldung.com/java-initialize-hashset)
|
- [Initializing HashSet at the Time of Construction](http://www.baeldung.com/java-initialize-hashset)
|
||||||
- [Guide to EnumSet](https://www.baeldung.com/java-enumset)
|
- [Guide to EnumSet](https://www.baeldung.com/java-enumset)
|
||||||
|
- [Set Operations in Java](https://www.baeldung.com/java-set-operations)
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.exception.numberformat</groupId>
|
||||||
|
<artifactId>core-java-exceptions</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>core-java-exceptions</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,154 @@
|
||||||
|
package com.baeldung.exception.numberformat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of examples tested to show cases where NumberFormatException is thrown and not thrown.
|
||||||
|
*/
|
||||||
|
public class NumberFormatExceptionUnitTest {
|
||||||
|
|
||||||
|
Logger LOG = Logger.getLogger(NumberFormatExceptionUnitTest.class.getName());
|
||||||
|
|
||||||
|
/* ---INTEGER FAIL CASES--- */
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenByteConstructor_whenAlphabetAsInput_thenFail() {
|
||||||
|
Byte byteInt = new Byte("one");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenShortConstructor_whenSpaceInInput_thenFail() {
|
||||||
|
Short shortInt = new Short("2 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenParseIntMethod_whenSpaceInInput_thenFail() {
|
||||||
|
Integer aIntPrim = Integer.parseInt("6000 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenParseIntMethod_whenUnderscoreInInput_thenFail() {
|
||||||
|
int bIntPrim = Integer.parseInt("6_000");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenIntegerValueOfMethod_whenCommaInInput_thenFail() {
|
||||||
|
Integer cIntPrim = Integer.valueOf("6,000");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenBigIntegerConstructor_whenDecimalInInput_thenFail() {
|
||||||
|
BigInteger bigInteger = new BigInteger("4.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenDecodeMethod_whenAlphabetInInput_thenFail() {
|
||||||
|
Long decodeInteger = Long.decode("64403L");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---INTEGER PASS CASES--- */
|
||||||
|
@Test
|
||||||
|
public void givenInvalidNumberInputs_whenOptimized_thenPass() {
|
||||||
|
Byte byteInt = new Byte("1");
|
||||||
|
assertEquals(1, byteInt.intValue());
|
||||||
|
|
||||||
|
Short shortInt = new Short("2 ".trim());
|
||||||
|
assertEquals(2, shortInt.intValue());
|
||||||
|
|
||||||
|
Integer aIntObj = Integer.valueOf("6");
|
||||||
|
assertEquals(6, aIntObj.intValue());
|
||||||
|
|
||||||
|
BigInteger bigInteger = new BigInteger("4");
|
||||||
|
assertEquals(4, bigInteger.intValue());
|
||||||
|
|
||||||
|
int aIntPrim = Integer.parseInt("6000 ".trim());
|
||||||
|
assertEquals(6000, aIntPrim);
|
||||||
|
|
||||||
|
int bIntPrim = Integer.parseInt("6_000".replaceAll("_", ""));
|
||||||
|
assertEquals(6000, bIntPrim);
|
||||||
|
|
||||||
|
int cIntPrim = Integer.parseInt("-6000");
|
||||||
|
assertEquals(-6000, cIntPrim);
|
||||||
|
|
||||||
|
Long decodeInteger = Long.decode("644032334");
|
||||||
|
assertEquals(644032334L, decodeInteger.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---DOUBLE FAIL CASES--- */
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenFloatConstructor_whenAlphabetInInput_thenFail() {
|
||||||
|
Float floatDecimalObj = new Float("one.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenDoubleConstructor_whenAlphabetInInput_thenFail() {
|
||||||
|
Double doubleDecimalObj = new Double("two.2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenBigDecimalConstructor_whenSpecialCharsInInput_thenFail() {
|
||||||
|
BigDecimal bigDecimalObj = new BigDecimal("3_0.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void givenParseDoubleMethod_whenCommaInInput_thenFail() {
|
||||||
|
double aDoublePrim = Double.parseDouble("4000,1");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---DOUBLE PASS CASES--- */
|
||||||
|
@Test
|
||||||
|
public void givenDoubleConstructor_whenDecimalInInput_thenPass() {
|
||||||
|
Double doubleDecimalObj = new Double("2.2");
|
||||||
|
assertEquals(2.2, doubleDecimalObj.doubleValue(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDoubleValueOfMethod_whenMinusInInput_thenPass() {
|
||||||
|
Double aDoubleObj = Double.valueOf("-6000");
|
||||||
|
assertEquals(-6000, aDoubleObj.doubleValue(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUsDecimalNumber_whenParsedWithNumberFormat_thenPass() throws ParseException {
|
||||||
|
Number parsedNumber = parseNumberWithLocale("4000.1", Locale.US);
|
||||||
|
assertEquals(4000.1, parsedNumber);
|
||||||
|
assertEquals(4000.1, parsedNumber.doubleValue(), 0);
|
||||||
|
assertEquals(4000, parsedNumber.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In most European countries (for example, France), comma is used as decimal in place of period.
|
||||||
|
* @throws ParseException if the input string contains special characters other than comma or decimal.
|
||||||
|
* In this test case, anything after decimal (period) is dropped when a European locale is set.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void givenEuDecimalNumberHasComma_whenParsedWithNumberFormat_thenPass() throws ParseException {
|
||||||
|
Number parsedNumber = parseNumberWithLocale("4000,1", Locale.FRANCE);
|
||||||
|
LOG.info("Number parsed is: " + parsedNumber);
|
||||||
|
assertEquals(4000.1, parsedNumber);
|
||||||
|
assertEquals(4000.1, parsedNumber.doubleValue(), 0);
|
||||||
|
assertEquals(4000, parsedNumber.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string into a number retaining all decimals, and symbols valid in a locale.
|
||||||
|
* @param number the input string for a number.
|
||||||
|
* @param locale the locale to consider while parsing a number.
|
||||||
|
* @return the generic number object which can represent multiple number types.
|
||||||
|
* @throws ParseException when input contains invalid characters.
|
||||||
|
*/
|
||||||
|
private Number parseNumberWithLocale(String number, Locale locale) throws ParseException {
|
||||||
|
locale = locale == null ? Locale.getDefault() : locale;
|
||||||
|
NumberFormat numberFormat = NumberFormat.getInstance(locale);
|
||||||
|
return numberFormat.parse(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -40,3 +40,4 @@
|
||||||
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
||||||
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)
|
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)
|
||||||
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||||
|
- [Introduction to the Java NIO Selector](https://www.baeldung.com/java-nio-selector)
|
||||||
|
|
|
@ -4,3 +4,5 @@
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Generic Constructors in Java](https://www.baeldung.com/java-generic-constructors)
|
- [Generic Constructors in Java](https://www.baeldung.com/java-generic-constructors)
|
||||||
|
- [Cannot Reference “X” Before Supertype Constructor Has Been Called](https://www.baeldung.com/java-cannot-reference-x-before-supertype-constructor-error)
|
||||||
|
- [Anonymous Classes in Java](https://www.baeldung.com/java-anonymous-classes)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant Articles
|
||||||
|
|
||||||
|
- [Void Type in Java](https://www.baeldung.com/java-void-type)
|
|
@ -51,3 +51,4 @@
|
||||||
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
||||||
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
||||||
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)
|
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)
|
||||||
|
- [Convert Hex to ASCII in Java](https://www.baeldung.com/java-convert-hex-to-ascii)
|
||||||
|
|
|
@ -454,7 +454,7 @@
|
||||||
<gson.version>2.8.2</gson.version>
|
<gson.version>2.8.2</gson.version>
|
||||||
|
|
||||||
<!-- util -->
|
<!-- util -->
|
||||||
<commons-lang3.version>3.5</commons-lang3.version>
|
<commons-lang3.version>3.9</commons-lang3.version>
|
||||||
<commons-io.version>2.5</commons-io.version>
|
<commons-io.version>2.5</commons-io.version>
|
||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
<decimal4j.version>1.0.3</decimal4j.version>
|
<decimal4j.version>1.0.3</decimal4j.version>
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class RootCauseFinder {
|
||||||
private AgeCalculator() {
|
private AgeCalculator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int calculateAge(String birthDate) throws CalculationException {
|
public static int calculateAge(String birthDate) {
|
||||||
if (birthDate == null || birthDate.isEmpty()) {
|
if (birthDate == null || birthDate.isEmpty()) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public class RootCauseFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalDate parseDate(String birthDateAsString) throws DateParseException {
|
private static LocalDate parseDate(String birthDateAsString) {
|
||||||
|
|
||||||
LocalDate birthDate;
|
LocalDate birthDate;
|
||||||
try {
|
try {
|
||||||
|
@ -62,14 +62,14 @@ public class RootCauseFinder {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CalculationException extends Exception {
|
static class CalculationException extends RuntimeException {
|
||||||
|
|
||||||
CalculationException(DateParseException ex) {
|
CalculationException(DateParseException ex) {
|
||||||
super(ex);
|
super(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DateParseException extends Exception {
|
static class DateParseException extends RuntimeException {
|
||||||
|
|
||||||
DateParseException(String input) {
|
DateParseException(String input) {
|
||||||
super(input);
|
super(input);
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>pre-jpms</module>
|
<module>pre-jpms</module>
|
||||||
|
<module>core-java-exceptions</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant Articles
|
||||||
|
|
||||||
|
- [Java 9 Migration Issues and Resolutions](https://www.baeldung.com/java-9-migration-issue)
|
|
@ -1,492 +0,0 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>core-java</artifactId>
|
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
|
||||||
<name>core-java</name>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-java</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<relativePath>../parent-java</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>${commons-io.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
<version>${commons-lang3.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.unix4j</groupId>
|
|
||||||
<artifactId>unix4j-command</artifactId>
|
|
||||||
<version>${unix4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.googlecode.grep4j</groupId>
|
|
||||||
<artifactId>grep4j</artifactId>
|
|
||||||
<version>${grep4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- web -->
|
|
||||||
<!-- marshalling -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
<version>${gson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- logging -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>${log4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>log4j-over-slf4j</artifactId>
|
|
||||||
<version>${org.slf4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>${lombok.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- test scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj-core.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.javamoney</groupId>
|
|
||||||
<artifactId>moneta</artifactId>
|
|
||||||
<version>${javamoney.moneta.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.owasp.esapi</groupId>
|
|
||||||
<artifactId>esapi</artifactId>
|
|
||||||
<version>${esapi.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.messaging.mq</groupId>
|
|
||||||
<artifactId>fscontext</artifactId>
|
|
||||||
<version>${fscontext.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.codepoetics</groupId>
|
|
||||||
<artifactId>protonpack</artifactId>
|
|
||||||
<version>${protonpack.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>one.util</groupId>
|
|
||||||
<artifactId>streamex</artifactId>
|
|
||||||
<version>${streamex.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.vavr</groupId>
|
|
||||||
<artifactId>vavr</artifactId>
|
|
||||||
<version>${vavr.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
|
||||||
<artifactId>jmh-core</artifactId>
|
|
||||||
<version>${jmh-core.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
|
||||||
<artifactId>jmh-generator-annprocess</artifactId>
|
|
||||||
<version>${jmh-generator-annprocess.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<version>${h2database.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- instrumentation -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.javassist</groupId>
|
|
||||||
<artifactId>javassist</artifactId>
|
|
||||||
<version>${javaassist.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun</groupId>
|
|
||||||
<artifactId>tools</artifactId>
|
|
||||||
<version>${sun.tools.version}</version>
|
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>core-java</finalName>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-dependencies</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-dependencies</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>${maven-jar-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addClasspath>true</addClasspath>
|
|
||||||
<classpathPrefix>libs/</classpathPrefix>
|
|
||||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
|
||||||
</manifest>
|
|
||||||
</archive>
|
|
||||||
<descriptorRefs>
|
|
||||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
|
||||||
</descriptorRefs>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>${maven-shade-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.jolira</groupId>
|
|
||||||
<artifactId>onejar-maven-plugin</artifactId>
|
|
||||||
<version>${onejar-maven-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<configuration>
|
|
||||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
|
||||||
<attachToBuild>true</attachToBuild>
|
|
||||||
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
|
||||||
<goal>one-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<version>${spring-boot-maven-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>repackage</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<classifier>spring-boot</classifier>
|
|
||||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>${exec-maven-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<executable>java</executable>
|
|
||||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
|
||||||
<arguments>
|
|
||||||
<argument>-Xmx300m</argument>
|
|
||||||
<argument>-XX:+UseParallelGC</argument>
|
|
||||||
<argument>-classpath</argument>
|
|
||||||
<classpath />
|
|
||||||
<argument>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</argument>
|
|
||||||
</arguments>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>${maven-javadoc-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>integration</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>integration-test</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/*ManualTest.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
<includes>
|
|
||||||
<include>**/*IntegrationTest.java</include>
|
|
||||||
<include>**/*IntTest.java</include>
|
|
||||||
</includes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<systemPropertyVariables>
|
|
||||||
<test.mime>json</test.mime>
|
|
||||||
</systemPropertyVariables>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>exec-maven-plugin</artifactId>
|
|
||||||
<version>${exec-maven-plugin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>run-benchmarks</id>
|
|
||||||
<!-- <phase>integration-test</phase> -->
|
|
||||||
<phase>none</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>exec</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<classpathScope>test</classpathScope>
|
|
||||||
<executable>java</executable>
|
|
||||||
<arguments>
|
|
||||||
<argument>-classpath</argument>
|
|
||||||
<classpath />
|
|
||||||
<argument>org.openjdk.jmh.Main</argument>
|
|
||||||
<argument>.*</argument>
|
|
||||||
</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<!-- java instrumentation profiles to build jars -->
|
|
||||||
<profile>
|
|
||||||
<id>buildAgentLoader</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<classifier>agentLoader</classifier>
|
|
||||||
<classesDirectory>target/classes</classesDirectory>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addClasspath>true</addClasspath>
|
|
||||||
</manifest>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
|
|
||||||
<includes>
|
|
||||||
<include>com/baeldung/instrumentation/application/AgentLoader.class</include>
|
|
||||||
<include>com/baeldung/instrumentation/application/Launcher.class</include>
|
|
||||||
</includes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>buildApplication</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<classifier>application</classifier>
|
|
||||||
<classesDirectory>target/classes</classesDirectory>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addClasspath>true</addClasspath>
|
|
||||||
</manifest>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
|
|
||||||
<includes>
|
|
||||||
<include>com/baeldung/instrumentation/application/MyAtm.class</include>
|
|
||||||
<include>com/baeldung/instrumentation/application/MyAtmApplication.class</include>
|
|
||||||
<include>com/baeldung/instrumentation/application/Launcher.class</include>
|
|
||||||
</includes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
<profile>
|
|
||||||
<id>buildAgent</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<classifier>agent</classifier>
|
|
||||||
<classesDirectory>target/classes</classesDirectory>
|
|
||||||
<archive>
|
|
||||||
<manifest>
|
|
||||||
<addClasspath>true</addClasspath>
|
|
||||||
</manifest>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
|
|
||||||
<includes>
|
|
||||||
<include>com/baeldung/instrumentation/agent/AtmTransformer.class</include>
|
|
||||||
<include>com/baeldung/instrumentation/agent/MyInstrumentationAgent.class</include>
|
|
||||||
</includes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
|
|
||||||
<!-- marshalling -->
|
|
||||||
<gson.version>2.8.2</gson.version>
|
|
||||||
|
|
||||||
<!-- util -->
|
|
||||||
<commons-lang3.version>3.9</commons-lang3.version>
|
|
||||||
<commons-io.version>2.5</commons-io.version>
|
|
||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
|
||||||
<decimal4j.version>1.0.3</decimal4j.version>
|
|
||||||
<unix4j.version>0.4</unix4j.version>
|
|
||||||
<grep4j.version>1.8.7</grep4j.version>
|
|
||||||
<fscontext.version>4.6-b01</fscontext.version>
|
|
||||||
<protonpack.version>1.13</protonpack.version>
|
|
||||||
<streamex.version>0.6.5</streamex.version>
|
|
||||||
<vavr.version>0.9.0</vavr.version>
|
|
||||||
|
|
||||||
<!-- testing -->
|
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
|
||||||
|
|
||||||
<!-- maven plugins -->
|
|
||||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
|
||||||
|
|
||||||
<javamoney.moneta.version>1.1</javamoney.moneta.version>
|
|
||||||
<h2database.version>1.4.197</h2database.version>
|
|
||||||
<esapi.version>2.1.0.1</esapi.version>
|
|
||||||
<jmh-core.version>1.19</jmh-core.version>
|
|
||||||
|
|
||||||
<jmh-generator-annprocess.version>1.19</jmh-generator-annprocess.version>
|
|
||||||
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
|
|
||||||
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
|
||||||
<onejar-maven-plugin.version>1.4.4</onejar-maven-plugin.version>
|
|
||||||
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>
|
|
||||||
<spring-boot-maven-plugin.version>2.0.3.RELEASE</spring-boot-maven-plugin.version>
|
|
||||||
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
|
|
||||||
<icu4j.version>61.1</icu4j.version>
|
|
||||||
<!-- instrumentation -->
|
|
||||||
<javaassist.version>3.21.0-GA</javaassist.version>
|
|
||||||
|
|
||||||
<sun.tools.version>1.8.0</sun.tools.version>
|
|
||||||
</properties>
|
|
||||||
</project>
|
|
|
@ -6,4 +6,5 @@
|
||||||
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
|
- [Kotlin Scope Functions](https://www.baeldung.com/kotlin-scope-functions)
|
||||||
- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations)
|
- [Kotlin Annotations](https://www.baeldung.com/kotlin-annotations)
|
||||||
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||||
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)
|
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)
|
||||||
|
- [Guide to JVM Platform Annotations in Kotlin](https://www.baeldung.com/kotlin-jvm-annotations)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class AmountBasedDiscountPolicy implements DiscountPolicy {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
if (order.totalCost()
|
||||||
|
.isGreaterThan(Money.of(CurrencyUnit.USD, 500.00))) {
|
||||||
|
return 0.10;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public interface DiscountPolicy {
|
||||||
|
double discount(Order order);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public class FlatDiscountPolicy implements DiscountPolicy {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.01;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.Visitable;
|
||||||
|
|
||||||
|
public class Order extends com.baeldung.ddd.order.Order implements Visitable<OrderVisitor> {
|
||||||
|
public Order(List<OrderLine> orderLines) {
|
||||||
|
super(orderLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money totalCost(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return totalCost().multipliedBy(1 - applyDiscountPolicy(discountPolicy), RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return discountPolicy.discount(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(OrderVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
public interface SpecialDiscountPolicy extends DiscountPolicy {
|
||||||
|
double discount(SpecialOrder order);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor;
|
||||||
|
|
||||||
|
public class SpecialOrder extends Order {
|
||||||
|
|
||||||
|
private boolean eligibleForExtraDiscount;
|
||||||
|
|
||||||
|
public SpecialOrder(List<OrderLine> orderLines) {
|
||||||
|
super(orderLines);
|
||||||
|
this.eligibleForExtraDiscount = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpecialOrder(List<OrderLine> orderLines, boolean eligibleForSpecialDiscount) {
|
||||||
|
super(orderLines);
|
||||||
|
this.eligibleForExtraDiscount = eligibleForSpecialDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEligibleForExtraDiscount() {
|
||||||
|
return eligibleForExtraDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) {
|
||||||
|
return discountPolicy.discount(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(OrderVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public class HtmlOrderViewCreator implements OrderVisitor {
|
||||||
|
|
||||||
|
private String html;
|
||||||
|
|
||||||
|
public String getHtml() {
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Order order) {
|
||||||
|
html = String.format("<p>Regular order total cost: %s</p>", order.totalCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(SpecialOrder order) {
|
||||||
|
html = String.format("<h1>Special Order</h1><p>total cost: %s</p>", order.totalCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public interface OrderVisitor {
|
||||||
|
void visit(Order order);
|
||||||
|
void visit(SpecialOrder order);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch.visitor;
|
||||||
|
|
||||||
|
public interface Visitable<V> {
|
||||||
|
void accept(V visitor);
|
||||||
|
}
|
|
@ -92,7 +92,7 @@ class JpaOrder {
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeLineItem(int line) {
|
void removeLineItem(int line) {
|
||||||
JpaOrderLine removedLine = orderLines.remove(line);
|
orderLines.remove(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrencyUnit(String currencyUnit) {
|
void setCurrencyUnit(String currencyUnit) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ class JpaProduct {
|
||||||
public JpaProduct(BigDecimal price, String currencyUnit) {
|
public JpaProduct(BigDecimal price, String currencyUnit) {
|
||||||
super();
|
super();
|
||||||
this.price = price;
|
this.price = price;
|
||||||
currencyUnit = currencyUnit;
|
this.currencyUnit = currencyUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.ddd.order;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
|
||||||
|
public class OrderFixtureUtils {
|
||||||
|
public static List<OrderLine> anyOrderLines() {
|
||||||
|
return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, 100)), 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<OrderLine> orderLineItemsWorthNDollars(int totalCost) {
|
||||||
|
return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, totalCost)), 1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.joda.money.CurrencyUnit;
|
||||||
|
import org.joda.money.Money;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
|
||||||
|
public class DoubleDispatchDiscountPolicyUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given regular order with items worth $100 total, " +
|
||||||
|
"when apply 10% discount policy, " +
|
||||||
|
"then cost after discount is $90"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
Order order = new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(100));
|
||||||
|
SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
Money totalCostAfterDiscount = order.totalCost(discountPolicy);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 90));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given special order eligible for extra discount with items worth $100 total, " +
|
||||||
|
"when apply 20% discount policy for extra discount orders, " +
|
||||||
|
"then cost after discount is $80"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test1() throws Exception {
|
||||||
|
// given
|
||||||
|
boolean eligibleForExtraDiscount = true;
|
||||||
|
Order order = new SpecialOrder(OrderFixtureUtils.orderLineItemsWorthNDollars(100), eligibleForExtraDiscount);
|
||||||
|
SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
if (order.isEligibleForExtraDiscount())
|
||||||
|
return 0.20;
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// when
|
||||||
|
Money totalCostAfterDiscount = order.totalCost(discountPolicy);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 80.00));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.visitor.HtmlOrderViewCreator;
|
||||||
|
|
||||||
|
public class HtmlOrderViewCreatorUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given collection of regular and special orders, " +
|
||||||
|
"when create HTML view using visitor for each order, " +
|
||||||
|
"then the dedicated view is created for each order"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
List<OrderLine> anyOrderLines = OrderFixtureUtils.anyOrderLines();
|
||||||
|
List<Order> orders = Arrays.asList(new Order(anyOrderLines), new SpecialOrder(anyOrderLines));
|
||||||
|
HtmlOrderViewCreator htmlOrderViewCreator = new HtmlOrderViewCreator();
|
||||||
|
|
||||||
|
// when
|
||||||
|
orders.get(0)
|
||||||
|
.accept(htmlOrderViewCreator);
|
||||||
|
String regularOrderHtml = htmlOrderViewCreator.getHtml();
|
||||||
|
orders.get(1)
|
||||||
|
.accept(htmlOrderViewCreator);
|
||||||
|
String specialOrderHtml = htmlOrderViewCreator.getHtml();
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(regularOrderHtml).containsPattern("<p>Regular order total cost: .*</p>");
|
||||||
|
assertThat(specialOrderHtml).containsPattern("<h1>Special Order</h1><p>total cost: .*</p>");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.Order;
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
import com.baeldung.ddd.order.OrderLine;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialDiscountPolicy;
|
||||||
|
import com.baeldung.ddd.order.doubledispatch.SpecialOrder;
|
||||||
|
|
||||||
|
public class MethodOverloadExampleUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given discount policy accepting special orders, " +
|
||||||
|
"when apply the policy on special order declared as regular order, " +
|
||||||
|
"then regular discount method is used"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
SpecialDiscountPolicy specialPolicy = new SpecialDiscountPolicy() {
|
||||||
|
@Override
|
||||||
|
public double discount(Order order) {
|
||||||
|
return 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double discount(SpecialOrder order) {
|
||||||
|
return 0.10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Order specialOrder = new SpecialOrder(anyOrderLines());
|
||||||
|
|
||||||
|
// when
|
||||||
|
double discount = specialPolicy.discount(specialOrder);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(discount).isEqualTo(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OrderLine> anyOrderLines() {
|
||||||
|
return OrderFixtureUtils.anyOrderLines();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.ddd.order.doubledispatch;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.baeldung.ddd.order.OrderFixtureUtils;
|
||||||
|
|
||||||
|
public class SingleDispatchDiscountPolicyUnitTest {
|
||||||
|
// @formatter:off
|
||||||
|
@DisplayName(
|
||||||
|
"given two discount policies, " +
|
||||||
|
"when use these policies, " +
|
||||||
|
"then single dispatch chooses the implementation based on runtime type"
|
||||||
|
)
|
||||||
|
// @formatter:on
|
||||||
|
@Test
|
||||||
|
void test() throws Exception {
|
||||||
|
// given
|
||||||
|
DiscountPolicy flatPolicy = new FlatDiscountPolicy();
|
||||||
|
DiscountPolicy amountPolicy = new AmountBasedDiscountPolicy();
|
||||||
|
Order orderWorth501Dollars = orderWorthNDollars(501);
|
||||||
|
|
||||||
|
// when
|
||||||
|
double flatDiscount = flatPolicy.discount(orderWorth501Dollars);
|
||||||
|
double amountDiscount = amountPolicy.discount(orderWorth501Dollars);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(flatDiscount).isEqualTo(0.01);
|
||||||
|
assertThat(amountDiscount).isEqualTo(0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Order orderWorthNDollars(int totalCost) {
|
||||||
|
return new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(totalCost));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Guava
|
||||||
|
|
||||||
|
## Relevant Articles:
|
||||||
|
|
||||||
|
- [Guava – Sets](http://www.baeldung.com/guava-sets)
|
||||||
|
- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset)
|
||||||
|
- [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial)
|
||||||
|
- [Guide to Guava Multiset](https://www.baeldung.com/guava-multiset)
|
|
@ -1,14 +1,9 @@
|
||||||
package org.baeldung.guava;
|
package org.baeldung.guava;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.AbstractSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.WeakHashMap;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class GuavaMapFromSet<K, V> extends AbstractMap<K, V> {
|
public class GuavaMapFromSet<K, V> extends AbstractMap<K, V> {
|
||||||
|
|
||||||
private class SingleEntry implements Entry<K, V> {
|
private class SingleEntry implements Entry<K, V> {
|
|
@ -1,15 +1,14 @@
|
||||||
package org.baeldung.guava;
|
package org.baeldung.guava;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import com.google.common.base.Function;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.junit.Test;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
public class GuavaMapFromSetUnitTest {
|
public class GuavaMapFromSetUnitTest {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package org.baeldung.guava;
|
package org.baeldung.guava;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import org.junit.Test;
|
|
||||||
import com.google.common.collect.ImmutableRangeSet;
|
import com.google.common.collect.ImmutableRangeSet;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
import com.google.common.collect.RangeSet;
|
import com.google.common.collect.RangeSet;
|
||||||
import com.google.common.collect.TreeRangeSet;
|
import com.google.common.collect.TreeRangeSet;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class GuavaRangeSetUnitTest {
|
public class GuavaRangeSetUnitTest {
|
||||||
|
|
||||||
|
@ -122,6 +121,5 @@ public class GuavaRangeSetUnitTest {
|
||||||
.add(Range.closed(0, 2))
|
.add(Range.closed(0, 2))
|
||||||
.add(Range.closed(3, 5))
|
.add(Range.closed(3, 5))
|
||||||
.add(Range.closed(5, 8)).build();
|
.add(Range.closed(5, 8)).build();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package org.baeldung.guava;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GuavaSetOperationsUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalculatingUnionOfSets_thenCorrect() {
|
||||||
|
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
||||||
|
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
||||||
|
|
||||||
|
final Set<Character> union = Sets.union(first, second);
|
||||||
|
assertThat(union, containsInAnyOrder('a', 'b', 'c', 'd'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalculatingCartesianProductOfSets_thenCorrect() {
|
||||||
|
final Set<Character> first = ImmutableSet.of('a', 'b');
|
||||||
|
final Set<Character> second = ImmutableSet.of('c', 'd');
|
||||||
|
final Set<List<Character>> result = Sets.cartesianProduct(ImmutableList.of(first, second));
|
||||||
|
|
||||||
|
final Function<List<Character>, String> func = new Function<List<Character>, String>() {
|
||||||
|
@Override
|
||||||
|
public final String apply(final List<Character> input) {
|
||||||
|
return Joiner
|
||||||
|
.on(" ").join(input);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Iterable<String> joined = Iterables.transform(result, func);
|
||||||
|
assertThat(joined, containsInAnyOrder("a c", "a d", "b c", "b d"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalculatingSetIntersection_thenCorrect() {
|
||||||
|
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
||||||
|
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
||||||
|
|
||||||
|
final Set<Character> intersection = Sets.intersection(first, second);
|
||||||
|
assertThat(intersection, containsInAnyOrder('b', 'c'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalculatingSetSymmetricDifference_thenCorrect() {
|
||||||
|
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
||||||
|
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
||||||
|
|
||||||
|
final Set<Character> intersection = Sets.symmetricDifference(first, second);
|
||||||
|
assertThat(intersection, containsInAnyOrder('a', 'd'));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCalculatingPowerSet_thenCorrect() {
|
||||||
|
final Set<Character> chars = ImmutableSet.of('a', 'b');
|
||||||
|
final Set<Set<Character>> result = Sets.powerSet(chars);
|
||||||
|
|
||||||
|
final Set<Character> empty = ImmutableSet.<Character> builder().build();
|
||||||
|
final Set<Character> a = ImmutableSet.of('a');
|
||||||
|
final Set<Character> b = ImmutableSet.of('b');
|
||||||
|
final Set<Character> aB = ImmutableSet.of('a', 'b');
|
||||||
|
|
||||||
|
assertThat(result, contains(empty, a, b, aB));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreatingRangeOfIntegersSet_thenCreated() {
|
||||||
|
final int start = 10;
|
||||||
|
final int end = 30;
|
||||||
|
final ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(start, end), DiscreteDomain.integers());
|
||||||
|
|
||||||
|
assertEquals(21, set.size());
|
||||||
|
assertEquals(10, set.first().intValue());
|
||||||
|
assertEquals(30, set.last().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenUsingRangeSet_thenCorrect() {
|
||||||
|
final RangeSet<Integer> rangeSet = TreeRangeSet.create();
|
||||||
|
rangeSet.add(Range.closed(1, 10));
|
||||||
|
rangeSet.add(Range.closed(12, 15));
|
||||||
|
|
||||||
|
assertEquals(2, rangeSet.asRanges().size());
|
||||||
|
|
||||||
|
rangeSet.add(Range.closed(10, 12));
|
||||||
|
assertTrue(rangeSet.encloses(Range.closed(1, 15)));
|
||||||
|
assertEquals(1, rangeSet.asRanges().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInsertDuplicatesInMultiSet_thenInserted() {
|
||||||
|
final Multiset<String> names = HashMultiset.create();
|
||||||
|
names.add("John");
|
||||||
|
names.add("Adam", 3);
|
||||||
|
names.add("John");
|
||||||
|
|
||||||
|
assertEquals(2, names.count("John"));
|
||||||
|
names.remove("John");
|
||||||
|
assertEquals(1, names.count("John"));
|
||||||
|
|
||||||
|
assertEquals(3, names.count("Adam"));
|
||||||
|
names.remove("Adam", 2);
|
||||||
|
assertEquals(1, names.count("Adam"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGetTopOcurringElementsWithMultiSet_thenCorrect() {
|
||||||
|
final Multiset<String> names = HashMultiset.create();
|
||||||
|
names.add("John");
|
||||||
|
names.add("Adam", 5);
|
||||||
|
names.add("Jane");
|
||||||
|
names.add("Tom", 2);
|
||||||
|
|
||||||
|
final Set<String> sorted = Multisets.copyHighestCountFirst(names).elementSet();
|
||||||
|
final List<String> topTwo = Lists.newArrayList(sorted).subList(0, 2);
|
||||||
|
assertEquals(2, topTwo.size());
|
||||||
|
assertEquals("Adam", topTwo.get(0));
|
||||||
|
assertEquals("Tom", topTwo.get(1));
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,13 +11,10 @@
|
||||||
- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection)
|
- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection)
|
||||||
- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial)
|
- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial)
|
||||||
- [Guava – Lists](http://www.baeldung.com/guava-lists)
|
- [Guava – Lists](http://www.baeldung.com/guava-lists)
|
||||||
- [Guava – Sets](http://www.baeldung.com/guava-sets)
|
|
||||||
- [Guava – Maps](http://www.baeldung.com/guava-maps)
|
- [Guava – Maps](http://www.baeldung.com/guava-maps)
|
||||||
- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap)
|
- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap)
|
||||||
- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset)
|
|
||||||
- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap)
|
- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap)
|
||||||
- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue)
|
- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue)
|
||||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||||
- [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial)
|
|
||||||
- [Guide to Guava Table](http://www.baeldung.com/guava-table)
|
- [Guide to Guava Table](http://www.baeldung.com/guava-table)
|
||||||
- [Guide to Guava ClassToInstanceMap](http://www.baeldung.com/guava-class-to-instance-map)
|
- [Guide to Guava ClassToInstanceMap](http://www.baeldung.com/guava-class-to-instance-map)
|
|
@ -111,120 +111,6 @@ public class GuavaCollectionTypesUnitTest {
|
||||||
assertThat(immutable, contains("John", "Adam", "Jane", "Tom"));
|
assertThat(immutable, contains("John", "Adam", "Jane", "Tom"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// sets
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCalculateUnionOfSets_thenCorrect() {
|
|
||||||
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
|
||||||
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
|
||||||
|
|
||||||
final Set<Character> union = Sets.union(first, second);
|
|
||||||
assertThat(union, containsInAnyOrder('a', 'b', 'c', 'd'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCalculateSetsProduct_thenCorrect() {
|
|
||||||
final Set<Character> first = ImmutableSet.of('a', 'b');
|
|
||||||
final Set<Character> second = ImmutableSet.of('c', 'd');
|
|
||||||
final Set<List<Character>> result = Sets.cartesianProduct(ImmutableList.of(first, second));
|
|
||||||
|
|
||||||
final Function<List<Character>, String> func = new Function<List<Character>, String>() {
|
|
||||||
@Override
|
|
||||||
public final String apply(final List<Character> input) {
|
|
||||||
return Joiner.on(" ").join(input);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final Iterable<String> joined = Iterables.transform(result, func);
|
|
||||||
assertThat(joined, containsInAnyOrder("a c", "a d", "b c", "b d"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCalculatingSetIntersection_thenCorrect() {
|
|
||||||
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
|
||||||
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
|
||||||
|
|
||||||
final Set<Character> intersection = Sets.intersection(first, second);
|
|
||||||
assertThat(intersection, containsInAnyOrder('b', 'c'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCalculatingSetSymmetricDifference_thenCorrect() {
|
|
||||||
final Set<Character> first = ImmutableSet.of('a', 'b', 'c');
|
|
||||||
final Set<Character> second = ImmutableSet.of('b', 'c', 'd');
|
|
||||||
|
|
||||||
final Set<Character> intersection = Sets.symmetricDifference(first, second);
|
|
||||||
assertThat(intersection, containsInAnyOrder('a', 'd'));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCalculatingPowerSet_thenCorrect() {
|
|
||||||
final Set<Character> chars = ImmutableSet.of('a', 'b');
|
|
||||||
final Set<Set<Character>> result = Sets.powerSet(chars);
|
|
||||||
|
|
||||||
final Set<Character> empty = ImmutableSet.<Character> builder().build();
|
|
||||||
final Set<Character> a = ImmutableSet.of('a');
|
|
||||||
final Set<Character> b = ImmutableSet.of('b');
|
|
||||||
final Set<Character> aB = ImmutableSet.of('a', 'b');
|
|
||||||
|
|
||||||
assertThat(result, contains(empty, a, b, aB));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCreateRangeOfIntegersSet_thenCreated() {
|
|
||||||
final int start = 10;
|
|
||||||
final int end = 30;
|
|
||||||
final ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(start, end), DiscreteDomain.integers());
|
|
||||||
|
|
||||||
assertEquals(21, set.size());
|
|
||||||
assertEquals(10, set.first().intValue());
|
|
||||||
assertEquals(30, set.last().intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenCreateRangeSet_thenCreated() {
|
|
||||||
final RangeSet<Integer> rangeSet = TreeRangeSet.create();
|
|
||||||
rangeSet.add(Range.closed(1, 10));
|
|
||||||
rangeSet.add(Range.closed(12, 15));
|
|
||||||
|
|
||||||
assertEquals(2, rangeSet.asRanges().size());
|
|
||||||
|
|
||||||
rangeSet.add(Range.closed(10, 12));
|
|
||||||
assertTrue(rangeSet.encloses(Range.closed(1, 15)));
|
|
||||||
assertEquals(1, rangeSet.asRanges().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenInsertDuplicatesInMultiSet_thenInserted() {
|
|
||||||
final Multiset<String> names = HashMultiset.create();
|
|
||||||
names.add("John");
|
|
||||||
names.add("Adam", 3);
|
|
||||||
names.add("John");
|
|
||||||
|
|
||||||
assertEquals(2, names.count("John"));
|
|
||||||
names.remove("John");
|
|
||||||
assertEquals(1, names.count("John"));
|
|
||||||
|
|
||||||
assertEquals(3, names.count("Adam"));
|
|
||||||
names.remove("Adam", 2);
|
|
||||||
assertEquals(1, names.count("Adam"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void whenGetTopUsingMultiSet_thenCorrect() {
|
|
||||||
final Multiset<String> names = HashMultiset.create();
|
|
||||||
names.add("John");
|
|
||||||
names.add("Adam", 5);
|
|
||||||
names.add("Jane");
|
|
||||||
names.add("Tom", 2);
|
|
||||||
|
|
||||||
final Set<String> sorted = Multisets.copyHighestCountFirst(names).elementSet();
|
|
||||||
final List<String> topTwo = Lists.newArrayList(sorted).subList(0, 2);
|
|
||||||
assertEquals(2, topTwo.size());
|
|
||||||
assertEquals("Adam", topTwo.get(0));
|
|
||||||
assertEquals("Tom", topTwo.get(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenCreateImmutableMap_thenCreated() {
|
public void whenCreateImmutableMap_thenCreated() {
|
||||||
final Map<String, Integer> salary = ImmutableMap.<String, Integer> builder().put("John", 1000).put("Jane", 1500).put("Adam", 2000).put("Tom", 2000).build();
|
final Map<String, Integer> salary = ImmutableMap.<String, Integer> builder().put("John", 1000).put("Jane", 1500).put("Adam", 2000).put("Tom", 2000).build();
|
||||||
|
|
|
@ -7,4 +7,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
||||||
|
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
|
||||||
- [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model)
|
- [Working with Tree Model Nodes in Jackson](https://www.baeldung.com/jackson-json-node-tree-model)
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
## Relevant Articles:
|
## Relevant Articles:
|
||||||
- [Map of Primitives in Java](https://www.baeldung.com/java-map-primitives)
|
- [Map of Primitives in Java](https://www.baeldung.com/java-map-primitives)
|
||||||
|
- [Copying a HashMap in Java](https://www.baeldung.com/java-copy-hashmap)
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
## Relevant Articles:
|
## Relevant Articles:
|
||||||
- [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar)
|
- [Converting Between LocalDate and XMLGregorianCalendar](https://www.baeldung.com/java-localdate-to-xmlgregoriancalendar)
|
||||||
|
- [Convert Time to Milliseconds in Java](https://www.baeldung.com/java-time-milliseconds)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
## Relevant Articles
|
||||||
|
|
||||||
|
- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting)
|
||||||
|
- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring)
|
|
@ -15,28 +15,6 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>commons-io</groupId>
|
|
||||||
<artifactId>commons-io</artifactId>
|
|
||||||
<version>${commons-io.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>${log4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-codec</groupId>
|
|
||||||
<artifactId>commons-codec</artifactId>
|
|
||||||
<version>${commons-codec.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- test scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
<artifactId>jmh-core</artifactId>
|
<artifactId>jmh-core</artifactId>
|
||||||
|
@ -57,11 +35,6 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.vdurmont</groupId>
|
|
||||||
<artifactId>emoji-java</artifactId>
|
|
||||||
<version>${emoji-java.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
@ -73,38 +46,18 @@
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
|
||||||
<version>${junit-jupiter-api.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-library</artifactId>
|
<artifactId>hamcrest-library</artifactId>
|
||||||
<version>${org.hamcrest.version}</version>
|
<version>${org.hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Added for password generation -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.passay</groupId>
|
|
||||||
<artifactId>passay</artifactId>
|
|
||||||
<version>${passay.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-text</artifactId>
|
<artifactId>commons-text</artifactId>
|
||||||
<version>${commons-text.version}</version>
|
<version>${commons-text.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ahocorasick</groupId>
|
|
||||||
<artifactId>ahocorasick</artifactId>
|
|
||||||
<version>${ahocorasick.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -131,18 +84,10 @@
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- util -->
|
|
||||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||||
<commons-codec.version>1.10</commons-codec.version>
|
|
||||||
<!-- testing -->
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
|
||||||
<icu4j.version>61.1</icu4j.version>
|
<icu4j.version>61.1</icu4j.version>
|
||||||
<guava.version>27.0.1-jre</guava.version>
|
<guava.version>27.0.1-jre</guava.version>
|
||||||
<emoji-java.version>4.0.0</emoji-java.version>
|
|
||||||
<junit-jupiter-api.version>5.3.1</junit-jupiter-api.version>
|
|
||||||
<passay.version>1.3.1</passay.version>
|
|
||||||
<commons-text.version>1.4</commons-text.version>
|
<commons-text.version>1.4</commons-text.version>
|
||||||
<ahocorasick.version>0.4.0</ahocorasick.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.baeldung.string.performance;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
|
||||||
|
|
||||||
|
@Fork(value = 3, warmups = 1)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
public class RemovingStopwordsPerformanceComparison {
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
private List<String> stopwords;
|
||||||
|
|
||||||
|
private String stopwordsRegex;
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
org.openjdk.jmh.Main.main(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() throws IOException {
|
||||||
|
data = new String(Files.readAllBytes(Paths.get("src/main/resources/shakespeare-hamlet.txt")));
|
||||||
|
data = data.toLowerCase();
|
||||||
|
stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt"));
|
||||||
|
stopwordsRegex = stopwords.stream().collect(Collectors.joining("|", "\\b(", ")\\b\\s?"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String removeManually() {
|
||||||
|
String[] allWords = data.split(" ");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(String word:allWords) {
|
||||||
|
if(! stopwords.contains(word)) {
|
||||||
|
builder.append(word);
|
||||||
|
builder.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String removeAll() {
|
||||||
|
ArrayList<String> allWords = Stream.of(data.split(" "))
|
||||||
|
.collect(Collectors.toCollection(ArrayList<String>::new));
|
||||||
|
allWords.removeAll(stopwords);
|
||||||
|
return allWords.stream().collect(Collectors.joining(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String replaceRegex() {
|
||||||
|
return data.replaceAll(stopwordsRegex, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
i
|
||||||
|
me
|
||||||
|
my
|
||||||
|
myself
|
||||||
|
we
|
||||||
|
our
|
||||||
|
ours
|
||||||
|
ourselves
|
||||||
|
you
|
||||||
|
your
|
||||||
|
yours
|
||||||
|
yourself
|
||||||
|
yourselves
|
||||||
|
he
|
||||||
|
him
|
||||||
|
his
|
||||||
|
himself
|
||||||
|
she
|
||||||
|
her
|
||||||
|
hers
|
||||||
|
herself
|
||||||
|
it
|
||||||
|
its
|
||||||
|
itself
|
||||||
|
they
|
||||||
|
them
|
||||||
|
their
|
||||||
|
theirs
|
||||||
|
themselves
|
||||||
|
what
|
||||||
|
which
|
||||||
|
who
|
||||||
|
whom
|
||||||
|
this
|
||||||
|
that
|
||||||
|
these
|
||||||
|
those
|
||||||
|
am
|
||||||
|
is
|
||||||
|
are
|
||||||
|
was
|
||||||
|
were
|
||||||
|
be
|
||||||
|
been
|
||||||
|
being
|
||||||
|
have
|
||||||
|
has
|
||||||
|
had
|
||||||
|
having
|
||||||
|
do
|
||||||
|
does
|
||||||
|
did
|
||||||
|
doing
|
||||||
|
a
|
||||||
|
an
|
||||||
|
the
|
||||||
|
and
|
||||||
|
but
|
||||||
|
if
|
||||||
|
or
|
||||||
|
because
|
||||||
|
as
|
||||||
|
until
|
||||||
|
while
|
||||||
|
of
|
||||||
|
at
|
||||||
|
by
|
||||||
|
for
|
||||||
|
with
|
||||||
|
about
|
||||||
|
against
|
||||||
|
between
|
||||||
|
into
|
||||||
|
through
|
||||||
|
during
|
||||||
|
before
|
||||||
|
after
|
||||||
|
above
|
||||||
|
below
|
||||||
|
to
|
||||||
|
from
|
||||||
|
up
|
||||||
|
down
|
||||||
|
in
|
||||||
|
out
|
||||||
|
on
|
||||||
|
off
|
||||||
|
over
|
||||||
|
under
|
||||||
|
again
|
||||||
|
further
|
||||||
|
then
|
||||||
|
once
|
||||||
|
here
|
||||||
|
there
|
||||||
|
when
|
||||||
|
where
|
||||||
|
why
|
||||||
|
how
|
||||||
|
all
|
||||||
|
any
|
||||||
|
both
|
||||||
|
each
|
||||||
|
few
|
||||||
|
more
|
||||||
|
most
|
||||||
|
other
|
||||||
|
some
|
||||||
|
such
|
||||||
|
no
|
||||||
|
nor
|
||||||
|
not
|
||||||
|
only
|
||||||
|
own
|
||||||
|
same
|
||||||
|
so
|
||||||
|
than
|
||||||
|
too
|
||||||
|
very
|
||||||
|
s
|
||||||
|
t
|
||||||
|
can
|
||||||
|
will
|
||||||
|
just
|
||||||
|
don
|
||||||
|
should
|
||||||
|
now
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.initialization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class StringInitializationUnitTest {
|
||||||
|
|
||||||
|
private String fieldString;
|
||||||
|
|
||||||
|
void printDeclaredOnlyString() {
|
||||||
|
String localVarString = null;
|
||||||
|
|
||||||
|
System.out.println(localVarString); // compilation error
|
||||||
|
System.out.println(fieldString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDeclaredFeldStringAndNullString_thenCompareEquals() {
|
||||||
|
String localVarString = null;
|
||||||
|
|
||||||
|
assertEquals(fieldString, localVarString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoStringsWithSameLiteral_thenCompareReferencesEquals() {
|
||||||
|
String literalOne = "Baeldung";
|
||||||
|
String literalTwo = "Baeldung";
|
||||||
|
|
||||||
|
assertTrue(literalOne == literalTwo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTwoStringsUsingNew_thenCompareReferencesNotEquals() {
|
||||||
|
String newStringOne = new String("Baeldung");
|
||||||
|
String newStringTwo = new String("Baeldung");
|
||||||
|
|
||||||
|
assertFalse(newStringOne == newStringTwo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyLiteralStringsAndNewObject_thenCompareEquals() {
|
||||||
|
String emptyLiteral = "";
|
||||||
|
String emptyNewString = new String("");
|
||||||
|
|
||||||
|
assertEquals(emptyLiteral, emptyNewString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEmptyStringObjects_thenCompareEquals() {
|
||||||
|
String emptyNewString = new String("");
|
||||||
|
String emptyNewStringTwo = new String();
|
||||||
|
|
||||||
|
assertEquals(emptyNewString, emptyNewStringTwo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.string;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class RemoveStopwordsUnitTest {
|
||||||
|
final String original = "The quick brown fox jumps over the lazy dog";
|
||||||
|
final String target = "quick brown fox jumps lazy dog";
|
||||||
|
static List<String> stopwords;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void loadStopwords() throws IOException {
|
||||||
|
stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsManually_thenSuccess() {
|
||||||
|
String[] allWords = original.toLowerCase()
|
||||||
|
.split(" ");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (String word : allWords) {
|
||||||
|
if (!stopwords.contains(word)) {
|
||||||
|
builder.append(word);
|
||||||
|
builder.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = builder.toString().trim();
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsUsingRemoveAll_thenSuccess() {
|
||||||
|
ArrayList<String> allWords = Stream.of(original.toLowerCase()
|
||||||
|
.split(" "))
|
||||||
|
.collect(Collectors.toCollection(ArrayList<String>::new));
|
||||||
|
allWords.removeAll(stopwords);
|
||||||
|
String result = allWords.stream().collect(Collectors.joining(" "));
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenRemoveStopwordsUsingRegex_thenSuccess() {
|
||||||
|
String stopwordsRegex = stopwords.stream()
|
||||||
|
.collect(Collectors.joining("|", "\\b(", ")\\b\\s?"));
|
||||||
|
String result = original.toLowerCase().replaceAll(stopwordsRegex, "");
|
||||||
|
assertEquals(result, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Creating New APIs and Views in JHipster](https://www.baeldung.com/jhipster-new-apis-and-views)
|
|
@ -18,14 +18,16 @@
|
||||||
<groupId>com.fasterxml.jackson.module</groupId>
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
<artifactId>jackson-module-kotlin</artifactId>
|
<artifactId>jackson-module-kotlin</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex.rxjava2</groupId>
|
||||||
|
<artifactId>rxkotlin</artifactId>
|
||||||
|
<version>2.3.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
package com.baeldung.kotlin.rxkotlin
|
||||||
|
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.functions.BiFunction
|
||||||
|
import io.reactivex.rxkotlin.*
|
||||||
|
import io.reactivex.subjects.PublishSubject
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
|
class RxKotlinTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenBooleanArrayToObserver_thenBooleanObserver() {
|
||||||
|
val observable = listOf(true, false, false).toObservable()
|
||||||
|
observable.test().assertValues(true, false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenBooleanArrayToFlowable_thenBooleanFlowable() {
|
||||||
|
val flowable = listOf(true, false, false).toFlowable()
|
||||||
|
flowable.buffer(2).test().assertValues(listOf(true, false), listOf(false))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenIntArrayToObserver_thenIntObserver() {
|
||||||
|
val observable = listOf(1, 1, 2, 3).toObservable()
|
||||||
|
observable.test().assertValues(1, 1, 2, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenIntArrayToFlowable_thenIntFlowable() {
|
||||||
|
val flowable = listOf(1, 1, 2, 3).toFlowable()
|
||||||
|
flowable.buffer(2).test().assertValues(listOf(1, 1), listOf(2, 3))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenObservablePairToMap_thenSingleNoDuplicates() {
|
||||||
|
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
|
||||||
|
val observable = list.toObservable()
|
||||||
|
val map = observable.toMap()
|
||||||
|
assertEquals(mapOf(Pair("a", 4), Pair("b", 2), Pair("c", 3)), map.blockingGet())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenObservablePairToMap_thenSingleWithDuplicates() {
|
||||||
|
val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4))
|
||||||
|
val observable = list.toObservable()
|
||||||
|
val map = observable.toMultimap()
|
||||||
|
assertEquals(
|
||||||
|
mapOf(Pair("a", listOf(1, 4)), Pair("b", listOf(2)), Pair("c", listOf(3))),
|
||||||
|
map.blockingGet())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenMergeAll_thenStream() {
|
||||||
|
val subject = PublishSubject.create<Observable<String>>()
|
||||||
|
val observable = subject.mergeAll()
|
||||||
|
val testObserver = observable.test()
|
||||||
|
subject.onNext(Observable.just("first", "second"))
|
||||||
|
testObserver.assertValues("first", "second")
|
||||||
|
subject.onNext(Observable.just("third", "fourth"))
|
||||||
|
subject.onNext(Observable.just("fifth"))
|
||||||
|
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenConcatAll_thenStream() {
|
||||||
|
val subject = PublishSubject.create<Observable<String>>()
|
||||||
|
val observable = subject.concatAll()
|
||||||
|
val testObserver = observable.test()
|
||||||
|
subject.onNext(Observable.just("first", "second"))
|
||||||
|
testObserver.assertValues("first", "second")
|
||||||
|
subject.onNext(Observable.just("third", "fourth"))
|
||||||
|
subject.onNext(Observable.just("fifth"))
|
||||||
|
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenSwitchLatest_thenStream() {
|
||||||
|
val subject = PublishSubject.create<Observable<String>>()
|
||||||
|
val observable = subject.switchLatest()
|
||||||
|
val testObserver = observable.test()
|
||||||
|
subject.onNext(Observable.just("first", "second"))
|
||||||
|
testObserver.assertValues("first", "second")
|
||||||
|
subject.onNext(Observable.just("third", "fourth"))
|
||||||
|
subject.onNext(Observable.just("fifth"))
|
||||||
|
testObserver.assertValues("first", "second", "third", "fourth", "fifth")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenMergeAllMaybes_thenObservable() {
|
||||||
|
val subject = PublishSubject.create<Maybe<Int>>()
|
||||||
|
val observable = subject.mergeAllMaybes()
|
||||||
|
val testObserver = observable.test()
|
||||||
|
subject.onNext(Maybe.just(1))
|
||||||
|
subject.onNext(Maybe.just(2))
|
||||||
|
subject.onNext(Maybe.empty())
|
||||||
|
testObserver.assertValues(1, 2)
|
||||||
|
subject.onNext(Maybe.error(Exception("")))
|
||||||
|
subject.onNext(Maybe.just(3))
|
||||||
|
testObserver.assertValues(1, 2).assertError(Exception::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenMerge_thenStream() {
|
||||||
|
val observables = mutableListOf(Observable.just("first", "second"))
|
||||||
|
val observable = observables.merge()
|
||||||
|
observables.add(Observable.just("third", "fourth"))
|
||||||
|
observables.add(Observable.error(Exception("e")))
|
||||||
|
observables.add(Observable.just("fifth"))
|
||||||
|
|
||||||
|
observable.test().assertValues("first", "second", "third", "fourth").assertError(Exception::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenMergeDelayError_thenStream() {
|
||||||
|
val observables = mutableListOf<Observable<String>>(Observable.error(Exception("e1")))
|
||||||
|
val observable = observables.mergeDelayError()
|
||||||
|
observables.add(Observable.just("1", "2"))
|
||||||
|
observables.add(Observable.error(Exception("e2")))
|
||||||
|
observables.add(Observable.just("3"))
|
||||||
|
|
||||||
|
observable.test().assertValues("1", "2", "3").assertError(Exception::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenCast_thenUniformType() {
|
||||||
|
val observable = Observable.just<Number>(1, 1, 2, 3)
|
||||||
|
observable.cast<Int>().test().assertValues(1, 1, 2, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenOfType_thenFilter() {
|
||||||
|
val observable = Observable.just(1, "and", 2, "and")
|
||||||
|
observable.ofType<Int>().test().assertValues(1, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenFunction_thenCompletable() {
|
||||||
|
var value = 0
|
||||||
|
val completable = { value = 3 }.toCompletable()
|
||||||
|
assertFalse(completable.test().isCancelled)
|
||||||
|
assertEquals(3, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenHelper_thenMoreIdiomaticKotlin() {
|
||||||
|
val zipWith = Observable.just(1).zipWith(Observable.just(2)) { a, b -> a + b }
|
||||||
|
zipWith.subscribeBy(onNext = { println(it) })
|
||||||
|
val zip = Observables.zip(Observable.just(1), Observable.just(2)) { a, b -> a + b }
|
||||||
|
zip.subscribeBy(onNext = { println(it) })
|
||||||
|
val zipOrig = Observable.zip(Observable.just(1), Observable.just(2), BiFunction<Int, Int, Int> { a, b -> a + b })
|
||||||
|
zipOrig.subscribeBy(onNext = { println(it) })
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,9 +54,8 @@ dependencies {
|
||||||
testCompile group: 'org.jetbrains.spek', name: 'spek-subject-extension', version: '1.1.5'
|
testCompile group: 'org.jetbrains.spek', name: 'spek-subject-extension', version: '1.1.5'
|
||||||
testCompile group: 'org.jetbrains.spek', name: 'spek-junit-platform-engine', version: '1.1.5'
|
testCompile group: 'org.jetbrains.spek', name: 'spek-junit-platform-engine', version: '1.1.5'
|
||||||
implementation 'com.beust:klaxon:3.0.1'
|
implementation 'com.beust:klaxon:3.0.1'
|
||||||
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
task runServer(type: JavaExec) {
|
task runServer(type: JavaExec) {
|
||||||
main = 'APIServer'
|
main = 'APIServer'
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
## Relevant Articles
|
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [A Guide to jBPM with Java](https://www.baeldung.com/jbpm-java)
|
||||||
- [Guide to Classgraph Library](https://www.baeldung.com/classgraph)
|
- [Guide to Classgraph Library](https://www.baeldung.com/classgraph)
|
||||||
|
- [Create a Java Command Line Program with Picocli](https://www.baeldung.com/java-picocli-create-command-line-program)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Get Log Output in JSON](https://www.baeldung.com/java-log-json-output)
|
- [Get Log Output in JSON](https://www.baeldung.com/java-log-json-output)
|
||||||
|
- [SLF4J Warning: Class Path Contains Multiple SLF4J Bindings](https://www.baeldung.com/slf4j-classpath-multiple-bindings)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search)
|
- [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search)
|
||||||
- [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring)
|
|
||||||
- [Introduction to Lettuce – the Java Redis Client](http://www.baeldung.com/java-redis-lettuce)
|
- [Introduction to Lettuce – the Java Redis Client](http://www.baeldung.com/java-redis-lettuce)
|
||||||
- [A Guide to Jdbi](http://www.baeldung.com/jdbi)
|
- [A Guide to Jdbi](http://www.baeldung.com/jdbi)
|
||||||
- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking)
|
- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking)
|
||||||
|
@ -13,3 +12,6 @@
|
||||||
- [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive)
|
- [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive)
|
||||||
- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
|
- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
|
||||||
- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)
|
- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)
|
||||||
|
- [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate)
|
||||||
|
- [Persisting Maps with Hibernate](https://www.baeldung.com/hibernate-persisting-maps)
|
||||||
|
- [Difference Between @Size, @Length, and @Column(length=value)](https://www.baeldung.com/jpa-size-length-column-differences)
|
||||||
|
|
|
@ -8,3 +8,4 @@
|
||||||
- [Introduction to the JDBC RowSet Interface in Java](http://www.baeldung.com/java-jdbc-rowset)
|
- [Introduction to the JDBC RowSet Interface in Java](http://www.baeldung.com/java-jdbc-rowset)
|
||||||
- [A Simple Guide to Connection Pooling in Java](https://www.baeldung.com/java-connection-pooling)
|
- [A Simple Guide to Connection Pooling in Java](https://www.baeldung.com/java-connection-pooling)
|
||||||
- [Guide to the JDBC ResultSet Interface](https://www.baeldung.com/jdbc-resultset)
|
- [Guide to the JDBC ResultSet Interface](https://www.baeldung.com/jdbc-resultset)
|
||||||
|
- [Types of SQL Joins](https://www.baeldung.com/sql-joins)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Persisting Maps with Hibernate](https://www.baeldung.com/hibernate-persisting-maps)
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
- [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping)
|
- [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping)
|
||||||
- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures)
|
- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures)
|
||||||
- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast)
|
- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast)
|
||||||
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
|
- [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph)
|
||||||
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
|
- [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time)
|
||||||
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)
|
- [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date)
|
||||||
- [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates)
|
- [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates)
|
||||||
|
- [Types of JPA Queries](https://www.baeldung.com/jpa-queries)
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.jpa.basicannotation;
|
||||||
|
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Course {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Basic(optional = false, fetch = FetchType.LAZY)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.baeldung.jpa.entity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
|
import com.baeldung.util.Gender;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="STUDENT")
|
||||||
|
public class Student {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
@Column(name = "STUDENT_NAME", length = 50, nullable = false, unique = false)
|
||||||
|
private String name;
|
||||||
|
@Transient
|
||||||
|
private Integer age;
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
private Date birthDate;
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private Gender gender;
|
||||||
|
|
||||||
|
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 Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(Integer age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBirthDate() {
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthDate(Date birthDate) {
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Gender getGender() {
|
||||||
|
return gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGender(Gender gender) {
|
||||||
|
this.gender = gender;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Article {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.ORDINAL)
|
||||||
|
private Status status;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private int priorityValue;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private Priority priority;
|
||||||
|
|
||||||
|
private Category category;
|
||||||
|
|
||||||
|
public Article() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostLoad
|
||||||
|
void fillTransient() {
|
||||||
|
if (priorityValue > 0) {
|
||||||
|
this.priority = Priority.of(priorityValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
void fillPersistent() {
|
||||||
|
if (priority != null) {
|
||||||
|
this.priorityValue = priority.getPriority();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Priority getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(Priority priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(Category category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public enum Category {
|
||||||
|
SPORT("S"), MUSIC("M"), TECHNOLOGY("T");
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
Category(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@Converter(autoApply = true)
|
||||||
|
public class CategoryConverter implements AttributeConverter<Category, String> {
|
||||||
|
@Override
|
||||||
|
public String convertToDatabaseColumn(Category category) {
|
||||||
|
if (category == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return category.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Category convertToEntityAttribute(final String code) {
|
||||||
|
if (code == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.of(Category.values())
|
||||||
|
.filter(c -> c.getCode().equals(code))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(IllegalArgumentException::new);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public enum Priority {
|
||||||
|
LOW(100), MEDIUM(200), HIGH(300);
|
||||||
|
|
||||||
|
private int priority;
|
||||||
|
|
||||||
|
private Priority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Priority of(int priority) {
|
||||||
|
return Stream.of(Priority.values())
|
||||||
|
.filter(p -> p.getPriority() == priority)
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(IllegalArgumentException::new);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
OPEN, REVIEW, APPROVED, REJECTED;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
INTERNAL, EXTERNAL;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.baeldung.util;
|
||||||
|
|
||||||
|
public enum Gender {
|
||||||
|
MALE,
|
||||||
|
FEMALE
|
||||||
|
}
|
|
@ -26,6 +26,8 @@
|
||||||
<persistence-unit name="jpa-h2">
|
<persistence-unit name="jpa-h2">
|
||||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
<class>com.baeldung.jpa.stringcast.Message</class>
|
<class>com.baeldung.jpa.stringcast.Message</class>
|
||||||
|
<class>com.baeldung.jpa.enums.Article</class>
|
||||||
|
<class>com.baeldung.jpa.enums.CategoryConverter</class>
|
||||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
|
||||||
|
@ -145,5 +147,20 @@
|
||||||
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|
||||||
</persistence>
|
<persistence-unit name="jpa-entity-definition">
|
||||||
|
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||||
|
<class>com.baeldung.jpa.entity.Student</class>
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<properties>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
|
||||||
|
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
|
||||||
|
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||||
|
<property name="javax.persistence.jdbc.password" value="" />
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||||
|
<property name="show_sql" value="true" />
|
||||||
|
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.jpa.basicannotation;
|
||||||
|
|
||||||
|
import org.hibernate.PropertyValueException;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class BasicAnnotationIntegrationTest {
|
||||||
|
|
||||||
|
private static EntityManager entityManager;
|
||||||
|
private static EntityManagerFactory entityManagerFactory;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void setup() {
|
||||||
|
entityManagerFactory = Persistence.createEntityManagerFactory("java-jpa-scheduled-day");
|
||||||
|
entityManager = entityManagerFactory.createEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenACourse_whenCourseNamePresent_shouldPersist() {
|
||||||
|
Course course = new Course();
|
||||||
|
course.setName("Computers");
|
||||||
|
|
||||||
|
entityManager.persist(course);
|
||||||
|
entityManager.flush();
|
||||||
|
entityManager.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = PropertyValueException.class)
|
||||||
|
public void givenACourse_whenCourseNameAbsent_shouldFail() {
|
||||||
|
Course course = new Course();
|
||||||
|
|
||||||
|
entityManager.persist(course);
|
||||||
|
entityManager.flush();
|
||||||
|
entityManager.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
if (entityManager != null) {
|
||||||
|
entityManager.close();
|
||||||
|
}
|
||||||
|
if (entityManagerFactory != null) {
|
||||||
|
entityManagerFactory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.baeldung.jpa.entity;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.util.Gender;
|
||||||
|
|
||||||
|
public class StudentEntityIntegrationTest {
|
||||||
|
|
||||||
|
private EntityManagerFactory emf;
|
||||||
|
private EntityManager em;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
emf = Persistence.createEntityManagerFactory("jpa-entity-definition");
|
||||||
|
em = emf.createEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void persistStudentThenRetrieveTheDetails() {
|
||||||
|
Student student = createStudentWithRelevantDetails();
|
||||||
|
persist(student);
|
||||||
|
clearThePersistenceContext();
|
||||||
|
List<Student> students = getStudentsFromTable();
|
||||||
|
checkAssertionsWith(students);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void destroy() {
|
||||||
|
if (em != null) {
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
if (emf != null) {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearThePersistenceContext() {
|
||||||
|
em.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAssertionsWith(List<Student> students) {
|
||||||
|
assertEquals(1, students.size());
|
||||||
|
Student john = students.get(0);
|
||||||
|
assertEquals(1L, john.getId().longValue());
|
||||||
|
assertEquals(null, john.getAge());
|
||||||
|
assertEquals("John", john.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Student> getStudentsFromTable() {
|
||||||
|
String selectQuery = "SELECT student FROM Student student";
|
||||||
|
TypedQuery<Student> selectFromStudentTypedQuery = em.createQuery(selectQuery, Student.class);
|
||||||
|
List<Student> students = selectFromStudentTypedQuery.getResultList();
|
||||||
|
return students;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void persist(Student student) {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
em.persist(student);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Student createStudentWithRelevantDetails() {
|
||||||
|
Student student = new Student();
|
||||||
|
student.setAge(20); // the 'age' field has been annotated with @Transient
|
||||||
|
student.setName("John");
|
||||||
|
Date date = getDate();
|
||||||
|
student.setBirthDate(date);
|
||||||
|
student.setGender(Gender.MALE);
|
||||||
|
return student;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date getDate() {
|
||||||
|
LocalDate localDate = LocalDate.of(2008, 7, 20);
|
||||||
|
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.baeldung.jpa.enums;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ArticleUnitTest {
|
||||||
|
|
||||||
|
private static EntityManager em;
|
||||||
|
private static EntityManagerFactory emFactory;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
Map properties = new HashMap();
|
||||||
|
properties.put("hibernate.show_sql", "true");
|
||||||
|
properties.put("hibernate.format_sql", "true");
|
||||||
|
emFactory = Persistence.createEntityManagerFactory("jpa-h2", properties);
|
||||||
|
em = emFactory.createEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPersistStatusEnumOrdinalValue() {
|
||||||
|
// given
|
||||||
|
Article article = new Article();
|
||||||
|
article.setId(1);
|
||||||
|
article.setTitle("ordinal title");
|
||||||
|
article.setStatus(Status.OPEN);
|
||||||
|
|
||||||
|
// when
|
||||||
|
EntityTransaction tx = em.getTransaction();
|
||||||
|
tx.begin();
|
||||||
|
em.persist(article);
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
// then
|
||||||
|
Article persistedArticle = em.find(Article.class, 1);
|
||||||
|
|
||||||
|
assertEquals(1, persistedArticle.getId());
|
||||||
|
assertEquals("ordinal title", persistedArticle.getTitle());
|
||||||
|
assertEquals(Status.OPEN, persistedArticle.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPersistTypeEnumStringValue() {
|
||||||
|
// given
|
||||||
|
Article article = new Article();
|
||||||
|
article.setId(2);
|
||||||
|
article.setTitle("string title");
|
||||||
|
article.setType(Type.EXTERNAL);
|
||||||
|
|
||||||
|
// when
|
||||||
|
EntityTransaction tx = em.getTransaction();
|
||||||
|
tx.begin();
|
||||||
|
em.persist(article);
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
// then
|
||||||
|
Article persistedArticle = em.find(Article.class, 2);
|
||||||
|
|
||||||
|
assertEquals(2, persistedArticle.getId());
|
||||||
|
assertEquals("string title", persistedArticle.getTitle());
|
||||||
|
assertEquals(Type.EXTERNAL, persistedArticle.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPersistPriorityIntValue() {
|
||||||
|
// given
|
||||||
|
Article article = new Article();
|
||||||
|
article.setId(3);
|
||||||
|
article.setTitle("callback title");
|
||||||
|
article.setPriority(Priority.HIGH);
|
||||||
|
|
||||||
|
// when
|
||||||
|
EntityTransaction tx = em.getTransaction();
|
||||||
|
tx.begin();
|
||||||
|
em.persist(article);
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
// then
|
||||||
|
Article persistedArticle = em.find(Article.class, 3);
|
||||||
|
|
||||||
|
assertEquals(3, persistedArticle.getId());
|
||||||
|
assertEquals("callback title", persistedArticle.getTitle());
|
||||||
|
assertEquals(Priority.HIGH, persistedArticle.getPriority());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPersistCategoryEnumConvertedValue() {
|
||||||
|
// given
|
||||||
|
Article article = new Article();
|
||||||
|
article.setId(4);
|
||||||
|
article.setTitle("converted title");
|
||||||
|
article.setCategory(Category.MUSIC);
|
||||||
|
|
||||||
|
// when
|
||||||
|
EntityTransaction tx = em.getTransaction();
|
||||||
|
tx.begin();
|
||||||
|
em.persist(article);
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
// then
|
||||||
|
Article persistedArticle = em.find(Article.class, 4);
|
||||||
|
|
||||||
|
assertEquals(4, persistedArticle.getId());
|
||||||
|
assertEquals("converted title", persistedArticle.getTitle());
|
||||||
|
assertEquals(Category.MUSIC, persistedArticle.getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
- [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb)
|
- [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb)
|
||||||
- [A Simple Tagging Implementation with MongoDB](http://www.baeldung.com/mongodb-tagging)
|
- [A Simple Tagging Implementation with MongoDB](http://www.baeldung.com/mongodb-tagging)
|
||||||
|
- [MongoDB BSON Guide](https://www.baeldung.com/mongodb-bson)
|
||||||
|
|
|
@ -55,5 +55,6 @@
|
||||||
<module>spring-hibernate-5</module>
|
<module>spring-hibernate-5</module>
|
||||||
<module>spring-hibernate4</module>
|
<module>spring-hibernate4</module>
|
||||||
<module>spring-jpa</module>
|
<module>spring-jpa</module>
|
||||||
|
<module>spring-persistence-simple</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
=========
|
=========
|
||||||
|
|
||||||
## Spring Data JPA Example Project
|
## Spring Data JPA Example Project
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
|
- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby)
|
||||||
|
- [JPA Join Types](https://www.baeldung.com/jpa-join-types)
|
||||||
|
- [Case Insensitive Queries with Spring Data Repository](https://www.baeldung.com/spring-data-case-insensitive-queries)
|
||||||
|
- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
|
||||||
|
- [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators)
|
||||||
|
- [Spring Data JPA and Null Parameters](https://www.baeldung.com/spring-data-jpa-null-parameters)
|
||||||
|
- [Spring Data JPA Projections](https://www.baeldung.com/spring-data-jpa-projections)
|
||||||
|
- [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
|
||||||
|
- [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete)
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.derivedquery.entity;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
@Table(name = "users")
|
||||||
|
@Entity
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private Integer age;
|
||||||
|
private ZonedDateTime birthDate;
|
||||||
|
private Boolean active;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String name, Integer age, ZonedDateTime birthDate, Boolean active) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(Integer age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getBirthDate() {
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthDate(ZonedDateTime birthDate) {
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(Boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.derivedquery.repository;
|
||||||
|
|
||||||
|
import com.baeldung.derivedquery.entity.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Integer> {
|
||||||
|
|
||||||
|
List<User> findByName(String name);
|
||||||
|
|
||||||
|
List<User> findByNameIs(String name);
|
||||||
|
|
||||||
|
List<User> findByNameEquals(String name);
|
||||||
|
|
||||||
|
List<User> findByNameIsNull();
|
||||||
|
|
||||||
|
List<User> findByNameNot(String name);
|
||||||
|
|
||||||
|
List<User> findByNameIsNot(String name);
|
||||||
|
|
||||||
|
List<User> findByNameStartingWith(String name);
|
||||||
|
|
||||||
|
List<User> findByNameEndingWith(String name);
|
||||||
|
|
||||||
|
List<User> findByNameContaining(String name);
|
||||||
|
|
||||||
|
List<User> findByNameLike(String name);
|
||||||
|
|
||||||
|
List<User> findByAgeLessThan(Integer age);
|
||||||
|
|
||||||
|
List<User> findByAgeLessThanEqual(Integer age);
|
||||||
|
|
||||||
|
List<User> findByAgeGreaterThan(Integer age);
|
||||||
|
|
||||||
|
List<User> findByAgeGreaterThanEqual(Integer age);
|
||||||
|
|
||||||
|
List<User> findByAgeBetween(Integer startAge, Integer endAge);
|
||||||
|
|
||||||
|
List<User> findByBirthDateAfter(ZonedDateTime birthDate);
|
||||||
|
|
||||||
|
List<User> findByBirthDateBefore(ZonedDateTime birthDate);
|
||||||
|
|
||||||
|
List<User> findByActiveTrue();
|
||||||
|
|
||||||
|
List<User> findByActiveFalse();
|
||||||
|
|
||||||
|
List<User> findByAgeIn(Collection<Integer> ages);
|
||||||
|
|
||||||
|
List<User> findByNameOrBirthDate(String name, ZonedDateTime birthDate);
|
||||||
|
|
||||||
|
List<User> findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);
|
||||||
|
|
||||||
|
List<User> findByNameOrderByName(String name);
|
||||||
|
|
||||||
|
List<User> findByNameOrderByNameDesc(String name);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.baeldung.like.model;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Movie {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||||
|
private Long id;
|
||||||
|
private String title;
|
||||||
|
private String director;
|
||||||
|
private String rating;
|
||||||
|
private int duration;
|
||||||
|
|
||||||
|
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 getDirector() {
|
||||||
|
return director;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirector(String director) {
|
||||||
|
this.director = director;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRating() {
|
||||||
|
return rating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRating(String rating) {
|
||||||
|
this.rating = rating;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDuration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuration(int duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.like.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
import com.baeldung.like.model.Movie;
|
||||||
|
|
||||||
|
public interface MovieRepository extends CrudRepository<Movie, Long> {
|
||||||
|
|
||||||
|
List<Movie> findByTitleContaining(String title);
|
||||||
|
|
||||||
|
List<Movie> findByTitleLike(String title);
|
||||||
|
|
||||||
|
List<Movie> findByTitleContains(String title);
|
||||||
|
|
||||||
|
List<Movie> findByTitleIsContaining(String title);
|
||||||
|
|
||||||
|
List<Movie> findByRatingStartsWith(String rating);
|
||||||
|
|
||||||
|
List<Movie> findByDirectorEndsWith(String director);
|
||||||
|
|
||||||
|
List<Movie> findByTitleContainingIgnoreCase(String title);
|
||||||
|
|
||||||
|
List<Movie> findByRatingNotContaining(String rating);
|
||||||
|
|
||||||
|
List<Movie> findByDirectorNotLike(String director);
|
||||||
|
|
||||||
|
@Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%")
|
||||||
|
List<Movie> searchByTitleLike(@Param("title") String title);
|
||||||
|
|
||||||
|
@Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%")
|
||||||
|
List<Movie> searchByRatingStartsWith(String rating);
|
||||||
|
|
||||||
|
//Escaping works in SpringBoot >= 2.4.1
|
||||||
|
//@Query("SELECT m FROM Movie m WHERE m.director LIKE %?#{escape([0])} escape ?#{escapeCharacter()}")
|
||||||
|
@Query("SELECT m FROM Movie m WHERE m.director LIKE %:#{[0]}")
|
||||||
|
List<Movie> searchByDirectorEndsWith(String director);
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
package com.baeldung.derivedquery.repository;
|
||||||
|
|
||||||
|
import com.baeldung.Application;
|
||||||
|
import com.baeldung.derivedquery.entity.User;
|
||||||
|
import com.baeldung.derivedquery.repository.UserRepository;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.After;
|
||||||
|
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.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = Application.class)
|
||||||
|
public class UserRepositoryTest {
|
||||||
|
|
||||||
|
private static final String USER_NAME_ADAM = "Adam";
|
||||||
|
private static final String USER_NAME_EVE = "Eve";
|
||||||
|
private static final ZonedDateTime BIRTHDATE = ZonedDateTime.now();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
|
||||||
|
User user1 = new User(USER_NAME_ADAM, 25, BIRTHDATE, true);
|
||||||
|
User user2 = new User(USER_NAME_ADAM, 20, BIRTHDATE, false);
|
||||||
|
User user3 = new User(USER_NAME_EVE, 20, BIRTHDATE, true);
|
||||||
|
User user4 = new User(null, 30, BIRTHDATE, false);
|
||||||
|
|
||||||
|
userRepository.saveAll(Arrays.asList(user1, user2, user3, user4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
|
||||||
|
userRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFindByName_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByName(USER_NAME_ADAM).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFindByNameIsNull_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameIsNull().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFindByNameNot_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(USER_NAME_EVE, userRepository.findByNameNot(USER_NAME_ADAM).get(0).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFindByNameStartingWith_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameStartingWith("A").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFindByNameEndingWith_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameEndingWith("e").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByNameContaining_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByNameContaining("v").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByNameLike_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameEndingWith("%d%m").size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeLessThan_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByAgeLessThan(25).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeLessThanEqual_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(3, userRepository.findByAgeLessThanEqual(25).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeGreaterThan_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(1, userRepository.findByAgeGreaterThan(25).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeGreaterThanEqual_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByAgeGreaterThanEqual(25).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeBetween_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(4, userRepository.findByAgeBetween(20, 30).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByBirthDateAfter_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
||||||
|
assertEquals(4, userRepository.findByBirthDateAfter(yesterday).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByBirthDateBefore_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
|
||||||
|
assertEquals(0, userRepository.findByBirthDateBefore(yesterday).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByActiveTrue_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByActiveTrue().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByActiveFalse_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByActiveFalse().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByAgeIn_thenReturnsCorrectResult() {
|
||||||
|
|
||||||
|
final List<Integer> ages = Arrays.asList(20, 25);
|
||||||
|
assertEquals(3, userRepository.findByAgeIn(ages).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByNameOrBirthDate() {
|
||||||
|
|
||||||
|
assertEquals(4, userRepository.findByNameOrBirthDate(USER_NAME_ADAM, BIRTHDATE).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByNameOrBirthDateAndActive() {
|
||||||
|
|
||||||
|
assertEquals(3, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenByNameOrderByName() {
|
||||||
|
|
||||||
|
assertEquals(2, userRepository.findByNameOrderByName(USER_NAME_ADAM).size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.baeldung.like;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.jdbc.Sql;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import com.baeldung.like.model.Movie;
|
||||||
|
import com.baeldung.like.repository.MovieRepository;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
@Sql(scripts = { "/test-movie-data.sql" })
|
||||||
|
@Sql(scripts = "/test-movie-cleanup.sql", executionPhase = AFTER_TEST_METHOD)
|
||||||
|
public class MovieRepositoryIntegrationTest {
|
||||||
|
@Autowired
|
||||||
|
private MovieRepository movieRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPartialTitle_WhenFindByTitleContaining_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByTitleContaining("in");
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
|
||||||
|
results = movieRepository.findByTitleLike("%in%");
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
|
||||||
|
results = movieRepository.findByTitleIsContaining("in");
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
|
||||||
|
results = movieRepository.findByTitleContains("in");
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStartOfRating_WhenFindByRatingStartsWith_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByRatingStartsWith("PG");
|
||||||
|
assertEquals(6, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLastName_WhenFindByDirectorEndsWith_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByDirectorEndsWith("Burton");
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPartialTitle_WhenFindByTitleContainingIgnoreCase_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByTitleContainingIgnoreCase("the");
|
||||||
|
assertEquals(2, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPartialTitle_WhenSearchByTitleLike_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.searchByTitleLike("in");
|
||||||
|
assertEquals(3, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStartOfRating_SearchFindByRatingStartsWith_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.searchByRatingStartsWith("PG");
|
||||||
|
assertEquals(6, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLastName_WhenSearchByDirectorEndsWith_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.searchByDirectorEndsWith("Burton");
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPartialRating_findByRatingNotContaining_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByRatingNotContaining("PG");
|
||||||
|
assertEquals(1, results.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPartialDirector_WhenFindByDirectorNotLike_ThenMoviesShouldReturn() {
|
||||||
|
List<Movie> results = movieRepository.findByDirectorNotLike("An%");
|
||||||
|
assertEquals(5, results.size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
DELETE FROM Movie;
|
|
@ -0,0 +1,7 @@
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
|
||||||
|
INSERT INTO movie(id, title, director, rating, duration) VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);
|
|
@ -6,7 +6,6 @@
|
||||||
- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
|
- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
|
||||||
- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
||||||
- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced)
|
- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced)
|
||||||
- [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query)
|
|
||||||
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
|
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
|
||||||
- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8)
|
- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8)
|
||||||
- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging)
|
- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging)
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Guide to Hibernate 4 with Spring](http://www.baeldung.com/hibernate-4-spring)
|
- [Guide to Hibernate 4 with Spring](http://www.baeldung.com/hibernate-4-spring)
|
||||||
- [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate)
|
|
||||||
- [Hibernate Pagination](http://www.baeldung.com/hibernate-pagination)
|
- [Hibernate Pagination](http://www.baeldung.com/hibernate-pagination)
|
||||||
- [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort)
|
- [Sorting with Hibernate](http://www.baeldung.com/hibernate-sort)
|
||||||
- [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
|
- [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa)
|
|
||||||
- [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring)
|
|
||||||
- [The DAO with JPA and Spring](http://www.baeldung.com/spring-dao-jpa)
|
- [The DAO with JPA and Spring](http://www.baeldung.com/spring-dao-jpa)
|
||||||
- [JPA Pagination](http://www.baeldung.com/jpa-pagination)
|
- [JPA Pagination](http://www.baeldung.com/jpa-pagination)
|
||||||
- [Sorting with JPA](http://www.baeldung.com/jpa-sort)
|
- [Sorting with JPA](http://www.baeldung.com/jpa-sort)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue