Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
ccf3708712
|
@ -89,7 +89,6 @@
|
|||
|
||||
<properties>
|
||||
<json-simple.version>1.1.1</json-simple.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
||||
<aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
|
|
|
@ -154,7 +154,6 @@
|
|||
<properties>
|
||||
<blade-mvc.version>2.0.14.RELEASE</blade-mvc.version>
|
||||
<bootstrap.version>4.2.1</bootstrap.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<lombok.version>1.18.4</lombok.version>
|
||||
<httpclient.version>4.5.6</httpclient.version>
|
||||
<httpmime.version>4.5.6</httpmime.version>
|
||||
|
|
|
@ -6,3 +6,4 @@ This module contains articles about Java 11 core features
|
|||
- [Guide to Java 8 Optional](https://www.baeldung.com/java-optional)
|
||||
- [Guide to Java Reflection](http://www.baeldung.com/java-reflection)
|
||||
- [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
|
||||
- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)
|
||||
|
|
|
@ -28,6 +28,29 @@
|
|||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-junit-jupiter</artifactId>
|
||||
<version>${mockserver.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -48,7 +71,9 @@
|
|||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||
<guava.version>29.0-jre</guava.version>
|
||||
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
||||
<assertj.version>3.17.2</assertj.version>
|
||||
<mockserver.version>5.11.1</mockserver.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.features;
|
||||
|
||||
public class MainClass {
|
||||
|
||||
private static boolean mainPrivateMethod() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class NestedClass {
|
||||
|
||||
boolean nestedPublicMethod() {
|
||||
return mainPrivateMethod();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.features;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.model.HttpStatusCode;
|
||||
import org.mockserver.socket.PortFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
|
||||
|
||||
class HttpClientIntegrationTest {
|
||||
|
||||
private static ClientAndServer mockServer;
|
||||
private static int port;
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() {
|
||||
port = PortFactory.findFreePort();
|
||||
mockServer = startClientAndServer(port);
|
||||
mockServer.when(new org.mockserver.model.HttpRequest().withMethod("GET"))
|
||||
.respond(new org.mockserver.model.HttpResponse()
|
||||
.withStatusCode(HttpStatusCode.OK_200.code())
|
||||
.withBody("Hello from the server!"));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void stopServer() {
|
||||
mockServer.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSampleHttpRequest_whenRequestIsSent_thenServerResponseIsReceived() throws IOException, InterruptedException {
|
||||
HttpClient httpClient = HttpClient.newBuilder()
|
||||
.version(HttpClient.Version.HTTP_2)
|
||||
.connectTimeout(Duration.ofSeconds(20))
|
||||
.build();
|
||||
HttpRequest httpRequest = HttpRequest.newBuilder()
|
||||
.GET()
|
||||
.uri(URI.create("http://localhost:" + port))
|
||||
.build();
|
||||
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
||||
assertThat(httpResponse.body()).isEqualTo("Hello from the server!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.features;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class JavaElevenFeaturesUnitTest {
|
||||
|
||||
@Test
|
||||
void givenMultilineString_whenExtractingNonBlankStrippedLines_thenLinesAreReturned() {
|
||||
String multilineString = "Baeldung helps \n \n developers \n explore Java.";
|
||||
List<String> lines = multilineString.lines()
|
||||
.filter(line -> !line.isBlank())
|
||||
.map(String::strip)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(lines).containsExactly("Baeldung helps", "developers", "explore Java.");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTemporaryFile_whenReadingStringContent_thenContentIsReturned(@TempDir Path tempDir) throws IOException {
|
||||
Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
|
||||
String fileContent = Files.readString(filePath);
|
||||
assertThat(fileContent).isEqualTo("Sample text");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSampleList_whenConvertingToArray_thenItemsRemainUnchanged() {
|
||||
List<String> sampleList = Arrays.asList("Java", "Kotlin");
|
||||
String[] sampleArray = sampleList.toArray(String[]::new);
|
||||
assertThat(sampleArray).containsExactly("Java", "Kotlin");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSampleList_whenConvertingToUppercaseString_thenUppercaseIsReturned() {
|
||||
List<String> sampleList = Arrays.asList("Java", "Kotlin");
|
||||
String resultString = sampleList.stream()
|
||||
.map((@Nonnull var x) -> x.toUpperCase())
|
||||
.collect(Collectors.joining(", "));
|
||||
assertThat(resultString).isEqualTo("JAVA, KOTLIN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSampleList_whenExtractingNonBlankValues_thenOnlyNonBlanksAreReturned() {
|
||||
List<String> sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
|
||||
List<String> withoutBlanks = sampleList.stream()
|
||||
.filter(Predicate.not(String::isBlank))
|
||||
.collect(Collectors.toList());
|
||||
assertThat(withoutBlanks).containsExactly("Java", "Kotlin");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.features;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class NestedClassesUnitTest {
|
||||
|
||||
@Test
|
||||
public void giveNestedClass_whenCallingMainClassPrivateMethod_thenNoExceptionIsThrown() {
|
||||
MainClass.NestedClass nestedInstance = new MainClass.NestedClass();
|
||||
assertThat(nestedInstance.nestedPublicMethod()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveNestedClass_whenCheckingNestmate_thenNestedClassIsReturned() {
|
||||
assertThat(MainClass.class.isNestmateOf(MainClass.NestedClass.class)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveNestedClass_whenCheckingNestHost_thenMainClassIsReturned() {
|
||||
assertThat(MainClass.NestedClass.class.getNestHost()).isEqualTo(MainClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void giveNestedClass_whenCheckingNestMembers_thenNestMembersAreReturned() {
|
||||
Set<String> nestedMembers = Arrays.stream(MainClass.NestedClass.class.getNestMembers())
|
||||
.map(Class::getName)
|
||||
.collect(Collectors.toSet());
|
||||
assertThat(nestedMembers).contains(MainClass.class.getName(), MainClass.NestedClass.class.getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
|
||||
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
|
||||
- [Java 12 New Features](https://www.baeldung.com/java-12-new-features)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package java.com.baeldung.newfeatures;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class CompactNumbersUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenNumber_thenCompactValues() {
|
||||
NumberFormat likesShort = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT);
|
||||
likesShort.setMaximumFractionDigits(2);
|
||||
assertEquals("2.59K", likesShort.format(2592));
|
||||
NumberFormat likesLong = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
|
||||
likesLong.setMaximumFractionDigits(2);
|
||||
assertEquals("2.59 thousand", likesShort.format(2592));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package java.com.baeldung.newfeatures;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FileMismatchUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenIdenticalFiles_thenShouldNotFindMismatch() throws IOException {
|
||||
Path filePath1 = Files.createTempFile("file1", ".txt");
|
||||
Path filePath2 = Files.createTempFile("file2", ".txt");
|
||||
Files.writeString(filePath1, "Java 12 Article");
|
||||
Files.writeString(filePath2, "Java 12 Article");
|
||||
long mismatch = Files.mismatch(filePath1, filePath2);
|
||||
assertEquals(-1, mismatch);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentFiles_thenShouldFindMismatch() throws IOException {
|
||||
Path filePath3 = Files.createTempFile("file3", ".txt");
|
||||
Path filePath4 = Files.createTempFile("file4", ".txt");
|
||||
Files.writeString(filePath3, "Java 12 Article");
|
||||
Files.writeString(filePath4, "Java 12 Tutorial");
|
||||
long mismatch = Files.mismatch(filePath3, filePath4);
|
||||
assertEquals(8, mismatch);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package java.com.baeldung.newfeatures;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StringUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenString_thenRevertValue() {
|
||||
String text = "Baeldung";
|
||||
String transformed = text.transform(value -> new StringBuilder(value).reverse().toString());
|
||||
assertEquals("gnudleaB", transformed);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package java.com.baeldung.newfeatures;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TeeingCollectorUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenSetOfNumbers_thenCalculateAverage() {
|
||||
double mean = Stream.of(1, 2, 3, 4, 5)
|
||||
.collect(Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, count) -> sum / count));
|
||||
assertEquals(3.0, mean);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${apache-commons-lang3.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
|
@ -68,7 +68,6 @@
|
|||
|
||||
<properties>
|
||||
<maven.compiler.release>15</maven.compiler.release>
|
||||
<apache-commons-lang3.version>3.11</apache-commons-lang3.version>
|
||||
<assertj.version>3.17.2</assertj.version>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
||||
|
|
|
@ -47,12 +47,12 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.11</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
|
||||
<assertj-core.version>3.10.0</assertj-core.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -68,11 +68,7 @@
|
|||
|
||||
<properties>
|
||||
<shade.plugin.version>3.2.0</shade.plugin.version>
|
||||
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
|
||||
<jmh.version>1.19</jmh.version>
|
||||
|
||||
<assertj-core.version>3.10.0</assertj-core.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -76,12 +76,8 @@
|
|||
|
||||
<properties>
|
||||
<shade.plugin.version>3.2.0</shade.plugin.version>
|
||||
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<guava.version>28.2-jre</guava.version>
|
||||
|
||||
<jmh.version>1.19</jmh.version>
|
||||
|
||||
<assertj-core.version>3.10.0</assertj-core.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -3,4 +3,4 @@
|
|||
This module contains articles about Java Character Class
|
||||
|
||||
### Relevant Articles:
|
||||
- Character#isAlphabetic vs Character#isLetter
|
||||
- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.10</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
<properties>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -10,11 +10,17 @@ import org.openjdk.jcstress.annotations.Outcome;
|
|||
import org.openjdk.jcstress.annotations.State;
|
||||
import org.openjdk.jcstress.infra.results.I_Result;
|
||||
|
||||
/**
|
||||
* This is defined as a manual test because it tries to simulate the race conditions
|
||||
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
|
||||
* This will help the CI jobs to ignore these tests and a developer to run them manually.
|
||||
*
|
||||
*/
|
||||
@JCStressTest
|
||||
@Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
|
||||
@Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
|
||||
@State
|
||||
public class MyCounterJCStressUnitTest {
|
||||
public class MyCounterJCStressManualTest {
|
||||
|
||||
private MyCounter counter;
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.umd.cs.mtc.MultithreadedTestCase;
|
||||
import edu.umd.cs.mtc.TestFramework;
|
||||
|
||||
public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
|
||||
/**
|
||||
* This is defined as a manual test because it tries to simulate the race conditions
|
||||
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
|
||||
* This will help the CI jobs to ignore these tests and a developer to run them manually.
|
||||
*
|
||||
*/
|
||||
public class MyCounterMultithreadedTCManualTest extends MultithreadedTestCase {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
|
@ -29,9 +34,8 @@ public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
|
|||
assertEquals(2, counter.getCount());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testCounter() throws Throwable {
|
||||
TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
|
||||
TestFramework.runManyTimes(new MyCounterMultithreadedTCManualTest(), 1000);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* This is defined as a manual test because it tries to simulate the race conditions
|
||||
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
|
||||
* This will help the CI jobs to ignore these tests and a developer to run them manually.
|
||||
*
|
||||
*/
|
||||
public class MyCounterSimpleManualTest {
|
||||
|
||||
@Test
|
||||
public void testCounter() {
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < 500; i++)
|
||||
counter.increment();
|
||||
assertEquals(500, counter.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCounterWithConcurrency() throws InterruptedException {
|
||||
int numberOfThreads = 100;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.execute(() -> {
|
||||
counter.increment();
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
|
||||
int numberOfThreads = 2;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.submit(() -> {
|
||||
try {
|
||||
counter.incrementWithWait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MyCounterSimpleUnitTest {
|
||||
|
||||
@Test
|
||||
public void testCounter() {
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < 500; i++)
|
||||
counter.increment();
|
||||
assertEquals(500, counter.getCount());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testCounterWithConcurrency() throws InterruptedException {
|
||||
int numberOfThreads = 100;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.execute(() -> {
|
||||
counter.increment();
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testSummationWithConcurrencyAndWait() throws InterruptedException {
|
||||
int numberOfThreads = 2;
|
||||
ExecutorService service = Executors.newFixedThreadPool(10);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfThreads);
|
||||
MyCounter counter = new MyCounter();
|
||||
for (int i = 0; i < numberOfThreads; i++) {
|
||||
service.submit(() -> {
|
||||
try {
|
||||
counter.incrementWithWait();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await();
|
||||
assertEquals(numberOfThreads, counter.getCount());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.code.tempusfugit.concurrency.ConcurrentRule;
|
||||
import com.google.code.tempusfugit.concurrency.RepeatingRule;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Repeating;
|
||||
|
||||
/**
|
||||
* This is defined as a manual test because it tries to simulate the race conditions
|
||||
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
|
||||
* This will help the CI jobs to ignore these tests and a developer to run them manually.
|
||||
*
|
||||
*/
|
||||
public class MyCounterTempusFugitManualTest {
|
||||
|
||||
@Rule
|
||||
public ConcurrentRule concurrently = new ConcurrentRule();
|
||||
@Rule
|
||||
public RepeatingRule rule = new RepeatingRule();
|
||||
|
||||
private static MyCounter counter = new MyCounter();
|
||||
|
||||
@Test
|
||||
@Concurrent(count = 2)
|
||||
@Repeating(repetition = 10)
|
||||
public void runsMultipleTimes() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
|
||||
assertEquals(counter.getCount(), 20);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.code.tempusfugit.concurrency.ConcurrentRule;
|
||||
import com.google.code.tempusfugit.concurrency.RepeatingRule;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
|
||||
import com.google.code.tempusfugit.concurrency.annotations.Repeating;
|
||||
|
||||
public class MyCounterTempusFugitUnitTest {
|
||||
|
||||
@Rule
|
||||
public ConcurrentRule concurrently = new ConcurrentRule();
|
||||
@Rule
|
||||
public RepeatingRule rule = new RepeatingRule();
|
||||
|
||||
private static MyCounter counter = new MyCounter();
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
@Concurrent(count = 2)
|
||||
@Repeating(repetition = 10)
|
||||
public void runsMultipleTimes() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
|
||||
assertEquals(counter.getCount(), 20);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.testing.threadtester.AnnotatedTestRunner;
|
||||
import com.google.testing.threadtester.ThreadedAfter;
|
||||
import com.google.testing.threadtester.ThreadedBefore;
|
||||
import com.google.testing.threadtester.ThreadedMain;
|
||||
import com.google.testing.threadtester.ThreadedSecondary;
|
||||
|
||||
/**
|
||||
* This is defined as a manual test because it tries to simulate the race conditions
|
||||
* in a concurrent program that is poorly designed and hence may fail nondeterministically.
|
||||
* This will help the CI jobs to ignore these tests and a developer to run them manually.
|
||||
*
|
||||
*/
|
||||
public class MyCounterThreadWeaverManualTest {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
@ThreadedBefore
|
||||
public void before() {
|
||||
counter = new MyCounter();
|
||||
}
|
||||
|
||||
@ThreadedMain
|
||||
public void mainThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedSecondary
|
||||
public void secondThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedAfter
|
||||
public void after() {
|
||||
assertEquals(2, counter.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCounter() {
|
||||
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.baeldung.concurrent;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.testing.threadtester.AnnotatedTestRunner;
|
||||
import com.google.testing.threadtester.ThreadedAfter;
|
||||
import com.google.testing.threadtester.ThreadedBefore;
|
||||
import com.google.testing.threadtester.ThreadedMain;
|
||||
import com.google.testing.threadtester.ThreadedSecondary;
|
||||
|
||||
public class MyCounterThreadWeaverUnitTest {
|
||||
|
||||
private MyCounter counter;
|
||||
|
||||
@ThreadedBefore
|
||||
public void before() {
|
||||
counter = new MyCounter();
|
||||
}
|
||||
|
||||
@ThreadedMain
|
||||
public void mainThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedSecondary
|
||||
public void secondThread() {
|
||||
counter.increment();
|
||||
}
|
||||
|
||||
@ThreadedAfter
|
||||
public void after() {
|
||||
assertEquals(2, counter.getCount());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testCounter() {
|
||||
new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Binary Semaphore vs Reentrant Lock](https://www.baeldung.com/java-binary-semaphore-vs-reentrant-lock)
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-concurrency-advanced-4</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-concurrency-advanced-4</name>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-concurrency-advanced-4</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,58 @@
|
|||
package com.baeldung.binarysemaphorereentrantlock;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class BinarySemaphoreVsReentrantLockUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenBinarySemaphore_whenAcquireAndRelease_thenCheckAvailablePermits() throws InterruptedException {
|
||||
Semaphore binarySemaphore = new Semaphore(1);
|
||||
try {
|
||||
binarySemaphore.acquire();
|
||||
assertEquals(0, binarySemaphore.availablePermits());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
binarySemaphore.release();
|
||||
assertEquals(1, binarySemaphore.availablePermits());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReentrantLock_whenLockAndUnlock_thenCheckHoldCountAndIsLocked() throws InterruptedException {
|
||||
ReentrantLock reentrantLock = new ReentrantLock();
|
||||
try {
|
||||
reentrantLock.lock();
|
||||
assertEquals(1, reentrantLock.getHoldCount());
|
||||
assertEquals(true, reentrantLock.isLocked());
|
||||
} finally {
|
||||
reentrantLock.unlock();
|
||||
assertEquals(0, reentrantLock.getHoldCount());
|
||||
assertEquals(false, reentrantLock.isLocked());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenReentrantLock_whenLockMultipleTimes_thenUnlockMultipleTimesToRelease() throws InterruptedException {
|
||||
ReentrantLock reentrantLock = new ReentrantLock();
|
||||
try {
|
||||
reentrantLock.lock();
|
||||
reentrantLock.lock();
|
||||
assertEquals(2, reentrantLock.getHoldCount());
|
||||
assertEquals(true, reentrantLock.isLocked());
|
||||
} finally {
|
||||
reentrantLock.unlock();
|
||||
assertEquals(1, reentrantLock.getHoldCount());
|
||||
assertEquals(true, reentrantLock.isLocked());
|
||||
|
||||
reentrantLock.unlock();
|
||||
assertEquals(0, reentrantLock.getHoldCount());
|
||||
assertEquals(false, reentrantLock.isLocked());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
test-link*
|
||||
0.*
|
|
@ -0,0 +1,8 @@
|
|||
## Core Java IO
|
||||
|
||||
This module contains articles about core Java input and output (IO)
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Java File Separator vs File Path Separator](https://www.baeldung.com/java-file-vs-file-path-separator)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-3)
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-io-4</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-io-4</name>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.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>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.fileseparator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
|
||||
public class FilePathSeparatorUnitTest {
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenCheckPathSeparator_thenResultIsAsExpectedOnWindows() throws IOException {
|
||||
assertEquals(";", File.pathSeparator);
|
||||
assertEquals(';', File.pathSeparatorChar);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenCheckPathSeparator_thenResultIsAsExpected() throws IOException {
|
||||
assertEquals(":", File.pathSeparator);
|
||||
assertEquals(':', File.pathSeparatorChar);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenBuildPathUsingString_thenResultIsAsExpectedOnWindows() throws IOException {
|
||||
String[] pathNames = { "path1", "path2", "path3" };
|
||||
String path = String.join(File.pathSeparator, pathNames);
|
||||
assertEquals("path1;path2;path3",path);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenBuildPathUsingString_thenResultIsAsExpected() throws IOException {
|
||||
String[] pathNames = { "path1", "path2", "path3" };
|
||||
String path = String.join(File.pathSeparator, pathNames);
|
||||
assertEquals("path1:path2:path3", path);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenbuildPathUsingStringJoiner_thenResultIsAsExpectedOnWindows() throws IOException {
|
||||
assertEquals("path1;path2", buildPathUsingStringJoiner("path1", "path2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenbuildPathUsingStringJoiner_thenResultIsAsExpected() throws IOException {
|
||||
assertEquals("path1:path2", buildPathUsingStringJoiner("path1", "path2"));
|
||||
}
|
||||
|
||||
private String buildPathUsingStringJoiner(String path1, String path2) {
|
||||
StringJoiner joiner = new StringJoiner(File.pathSeparator);
|
||||
joiner.add(path1);
|
||||
joiner.add(path2);
|
||||
return joiner.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.baeldung.fileseparator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
|
||||
public class FileSeparatorUnitTest {
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenCheckFileSeparator_thenCorrectOnWindows() {
|
||||
assertEquals("\\", File.separator);
|
||||
assertEquals('\\', File.separatorChar);
|
||||
|
||||
String fileSeparator = FileSystems.getDefault().getSeparator();
|
||||
assertEquals("\\",fileSeparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenCheckFileSeparator_thenCorrect() {
|
||||
assertEquals("/", File.separator);
|
||||
assertEquals('/', File.separatorChar);
|
||||
|
||||
String fileSeparator = FileSystems.getDefault().getSeparator();
|
||||
assertEquals("/",fileSeparator);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenBuildFilePathUsingPathsClass_thenCorrectOnWindows() {
|
||||
Path path = Paths.get("dir1", "dir2");
|
||||
assertEquals("dir1\\dir2", path.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenBuildFilePathUsingPathsClass_thenCorrect() {
|
||||
Path path = Paths.get("dir1", "dir2");
|
||||
assertEquals("dir1/dir2", path.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpectedOnWindows() {
|
||||
File file = new File("file1", "file2");
|
||||
assertEquals("file1\\file2", file.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledOnOs({ OS.LINUX, OS.MAC })
|
||||
public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpected() {
|
||||
File file = new File("file1", "file2");
|
||||
assertEquals("file1/file2", file.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.constantpool;
|
||||
|
||||
public class ConstantPool {
|
||||
|
||||
public void sayHello() {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
|
@ -69,7 +69,6 @@
|
|||
<jmh-generator.version>1.19</jmh-generator.version>
|
||||
<assertj.version>3.12.2</assertj.version>
|
||||
<commons.beanutils.version>1.9.4</commons.beanutils.version>
|
||||
<commons-lang3.version>3.10</commons-lang3.version>
|
||||
<guava.version>29.0-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
|
||||
- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
|
||||
- [Largest Power of 2 That Is Less Than the Given Number with Java](https://www.baeldung.com/java-largest-power-of-2-less-than-number)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)[[Next -->]](/core-java-modules/core-java-lang-math-3)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
=========
|
||||
|
||||
## Core Java 8 Cookbooks and Examples - Part 3
|
||||
|
||||
### Relevant articles:
|
||||
|
||||
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
||||
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-lang-math-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>core-java-lang-math-3</name>
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.objecthunter</groupId>
|
||||
<artifactId>exp4j</artifactId>
|
||||
<version>0.4.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fathzer</groupId>
|
||||
<artifactId>javaluator</artifactId>
|
||||
<version>3.0.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,91 @@
|
|||
package com.baeldung.math.evaluate;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.fathzer.soft.javaluator.DoubleEvaluator;
|
||||
import com.fathzer.soft.javaluator.StaticVariableSet;
|
||||
|
||||
import net.objecthunter.exp4j.Expression;
|
||||
import net.objecthunter.exp4j.ExpressionBuilder;
|
||||
|
||||
public class EvalauteMathExpressionsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() {
|
||||
Expression expression = new ExpressionBuilder("3+2").build();
|
||||
double result = expression.evaluate();
|
||||
Assertions.assertEquals(5, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoVariables_whenCallEvaluateMethod_thenSuccess() {
|
||||
Expression expression = new ExpressionBuilder("3x+2y").variables("x", "y")
|
||||
.build()
|
||||
.setVariable("x", 2)
|
||||
.setVariable("y", 3);
|
||||
double result = expression.evaluate();
|
||||
Assertions.assertEquals(12, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMathFunctions_whenCallEvaluateMethod_thenSuccess() {
|
||||
Expression expression = new ExpressionBuilder("sin(x)*sin(x)+cos(x)*cos(x)").variables("x")
|
||||
.build()
|
||||
.setVariable("x", 0.5);
|
||||
double result = expression.evaluate();
|
||||
Assertions.assertEquals(1, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExpression_whenCallEvaluateMethod_thenSuccess() {
|
||||
String expression = "3+2";
|
||||
DoubleEvaluator eval = new DoubleEvaluator();
|
||||
Double result = eval.evaluate(expression);
|
||||
Assertions.assertEquals(5, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVariables_whenCallEvaluateMethod_thenSuccess() {
|
||||
String expression = "3*x+2*y";
|
||||
DoubleEvaluator eval = new DoubleEvaluator();
|
||||
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
|
||||
variables.set("x", 2.0);
|
||||
variables.set("y", 3.0);
|
||||
Double result = eval.evaluate(expression, variables);
|
||||
Assertions.assertEquals(12, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMathFunction_whenCallEvaluateMethod_thenSuccess() {
|
||||
String expression = "sin(x)*sin(x)+cos(x)*cos(x)";
|
||||
DoubleEvaluator eval = new DoubleEvaluator();
|
||||
StaticVariableSet<Double> variables = new StaticVariableSet<Double>();
|
||||
variables.set("x", 0.5);
|
||||
Double result = eval.evaluate(expression, variables);
|
||||
Assertions.assertEquals(1, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJavaScriptingApiAndSimpleExpression_whenCallEvalMethod_thenSuccess() throws ScriptException {
|
||||
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
|
||||
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
|
||||
String expression = "3+2";
|
||||
Integer result = (Integer) scriptEngine.eval(expression);
|
||||
Assertions.assertEquals(5, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJavaScriptingApi_whenCallEvalMethod_thenSuccess() throws ScriptException {
|
||||
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
|
||||
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
|
||||
String expression = "x=2; y=3; 3*x+2*y;";
|
||||
Double result = (Double) scriptEngine.eval(expression);
|
||||
Assertions.assertEquals(12, result);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,7 @@ import java.util.logging.Logger;
|
|||
public class OutputStreamExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Logger log = Logger.getLogger(OutputStreamExample.class.getName());
|
||||
log.log(Level.INFO, Integer.toString(sum(1,2)));
|
||||
System.out.println(sum(1,2));
|
||||
}
|
||||
|
||||
public static int sum(int a, int b) {
|
||||
|
|
|
@ -5,10 +5,10 @@ import static org.junit.Assert.assertTrue;
|
|||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.String;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.lang.Integer;
|
||||
|
||||
|
@ -88,4 +88,21 @@ class ProcessUnderstandingUnitTest {
|
|||
.filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
|
||||
.count()) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3() throws IOException {
|
||||
|
||||
Runtime.getRuntime()
|
||||
.exec("javac -cp src src/main/java/com/baeldung/java9/process/OutputStreamExample.java"
|
||||
.replace("/", File.separator));
|
||||
|
||||
Process process = Runtime.getRuntime()
|
||||
.exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"
|
||||
.replace("/", File.separator));
|
||||
|
||||
BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
int value = Integer.parseInt(output.readLine());
|
||||
|
||||
assertEquals(3, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@ import java.awt.Robot;
|
|||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Ignore
|
||||
public class ScreenshotUnitTest {
|
||||
|
||||
@Test
|
||||
|
@ -43,7 +45,6 @@ public class ScreenshotUnitTest {
|
|||
|
||||
// This methods needs a component as a parameter and can only be run from an application with a GUI
|
||||
@Test
|
||||
@Disabled
|
||||
public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
|
||||
Rectangle componentRect = component.getBounds();
|
||||
BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<diff-match-path.version>1.2</diff-match-path.version>
|
||||
</properties>
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<guava.version>28.1-jre</guava.version>
|
||||
</properties>
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
<ahocorasick.version>0.4.0</ahocorasick.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
|
|
|
@ -112,7 +112,6 @@
|
|||
<properties>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<validation-api.version>2.0.0.Final</validation-api.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<guava.version>28.2-jre</guava.version>
|
||||
<hibernate-validator.version>6.0.2.Final</hibernate-validator.version>
|
||||
<javax.el-api.version>3.0.0</javax.el-api.version>
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
</properties>
|
||||
|
|
|
@ -18,15 +18,6 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
|||
@PrepareForTest({ LocalDateTime.class })
|
||||
public class LocalDateTimeUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
String dateTimeExpected = "2014-12-22T10:15:30";
|
||||
LocalDateTime now = LocalDateTime.now(clock);
|
||||
|
||||
assertThat(now).isEqualTo(dateTimeExpected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
|
||||
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<module>core-java-concurrency-advanced</module>
|
||||
<module>core-java-concurrency-advanced-2</module>
|
||||
<module>core-java-concurrency-advanced-3</module>
|
||||
<module>core-java-concurrency-advanced-4</module>
|
||||
<module>core-java-concurrency-basic</module>
|
||||
<module>core-java-concurrency-basic-2</module>
|
||||
<module>core-java-concurrency-collections</module>
|
||||
|
@ -67,6 +68,7 @@
|
|||
<module>core-java-io</module>
|
||||
<module>core-java-io-2</module>
|
||||
<module>core-java-io-3</module>
|
||||
<module>core-java-io-4</module>
|
||||
<module>core-java-io-apis</module>
|
||||
<module>core-java-io-conversions</module>
|
||||
<module>core-java-io-conversions-2</module>
|
||||
|
@ -82,6 +84,7 @@
|
|||
<module>core-java-lang-3</module>
|
||||
<module>core-java-lang-math</module>
|
||||
<module>core-java-lang-math-2</module>
|
||||
<module>core-java-lang-math-3</module>
|
||||
<module>core-java-lang-oop-constructors</module>
|
||||
<module>core-java-lang-oop-patterns</module>
|
||||
<module>core-java-lang-oop-generics</module>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)
|
|
@ -9,4 +9,5 @@ This module contains articles about Jackson conversions.
|
|||
- [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv)
|
||||
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
|
||||
- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
|
||||
- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast)
|
||||
- More articles: [[<-- prev]](../jackson-conversions)
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Book {
|
||||
private Integer bookId;
|
||||
private String title;
|
||||
private String author;
|
||||
|
||||
public Book() {}
|
||||
|
||||
public Book(Integer bookId, String title, String author) {
|
||||
this.bookId = bookId;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Book)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Book book = (Book) o;
|
||||
|
||||
if (!Objects.equals(bookId, book.bookId)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(title, book.title)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(author, book.author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = bookId != null ? bookId.hashCode() : 0;
|
||||
result = 31 * result + (title != null ? title.hashCode() : 0);
|
||||
result = 31 * result + (author != null ? author.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Integer getBookId() {
|
||||
return bookId;
|
||||
}
|
||||
|
||||
public void setBookId(Integer bookId) {
|
||||
this.bookId = bookId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JsonToCollectionUtil {
|
||||
|
||||
private JsonToCollectionUtil(){}
|
||||
|
||||
public static <T> List<T> jsonArrayToList(String json, Class<T> elementClass) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
|
||||
return objectMapper.readValue(json, listType);
|
||||
}
|
||||
|
||||
public static <T> List<T> jsonArrayToList2(String json, Class<T> elementClass) throws IOException {
|
||||
return new ObjectMapper().readValue(json, new TypeReference<List<T>>() {});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
[ {
|
||||
"bookId" : 1,
|
||||
"title" : "A Song of Ice and Fire",
|
||||
"author" : "George R. R. Martin"
|
||||
}, {
|
||||
"bookId" : 2,
|
||||
"title" : "The Hitchhiker's Guide to the Galaxy",
|
||||
"author" : "Douglas Adams"
|
||||
}, {
|
||||
"bookId" : 3,
|
||||
"title" : "Hackers And Painters",
|
||||
"author" : "Paul Graham"
|
||||
} ]
|
|
@ -0,0 +1,17 @@
|
|||
<ArrayList>
|
||||
<item>
|
||||
<bookId>1</bookId>
|
||||
<title>A Song of Ice and Fire</title>
|
||||
<author>George R. R. Martin</author>
|
||||
</item>
|
||||
<item>
|
||||
<bookId>2</bookId>
|
||||
<title>The Hitchhiker's Guide to the Galaxy</title>
|
||||
<author>Douglas Adams</author>
|
||||
</item>
|
||||
<item>
|
||||
<bookId>3</bookId>
|
||||
<title>Hackers And Painters</title>
|
||||
<author>Paul Graham</author>
|
||||
</item>
|
||||
</ArrayList>
|
|
@ -0,0 +1,130 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.CollectionType;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
public class DeserializeToJavaCollectionUnitTest {
|
||||
private ObjectMapper objectMapper;
|
||||
private XmlMapper xmlMapper;
|
||||
private List<Book> expectedBookList;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
objectMapper = new ObjectMapper();
|
||||
xmlMapper = new XmlMapper();
|
||||
expectedBookList = Lists.newArrayList(
|
||||
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
|
||||
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
|
||||
new Book(3, "Hackers And Painters", "Paul Graham"));
|
||||
}
|
||||
|
||||
private String readFile(String path) {
|
||||
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
|
||||
/*====================
|
||||
* JSON tests
|
||||
*====================
|
||||
*/
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, ArrayList.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class);
|
||||
List<Book> bookList = objectMapper.readValue(jsonString, listType);
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonString);
|
||||
List<Book> bookList = objectMapper.convertValue(jsonNode, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonString);
|
||||
List<Book> bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
/*====================
|
||||
* XML tests
|
||||
*====================
|
||||
*/
|
||||
@Test
|
||||
void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List<Book> bookList = xmlMapper.readValue(xml, ArrayList.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List<Book> bookList = xmlMapper.readValue(xml, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List node = xmlMapper.readValue(xml, List.class);
|
||||
List<Book> bookList = xmlMapper.convertValue(node, new TypeReference<List<Book>>() {});
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
|
||||
String xml = readFile("/to-java-collection/books.xml");
|
||||
List node = xmlMapper.readValue(xml, List.class);
|
||||
List<Book> bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.jackson.tocollection;
|
||||
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
class JsonToCollectionUtilUnitTest {
|
||||
|
||||
private List<Book> expectedBookList;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
expectedBookList = Lists.newArrayList(
|
||||
new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
|
||||
new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
|
||||
new Book(3, "Hackers And Painters", "Paul Graham"));
|
||||
}
|
||||
|
||||
private String readFile(String path) {
|
||||
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class);
|
||||
assertThat(bookList.get(0)).isInstanceOf(Book.class);
|
||||
assertThat(bookList).isEqualTo(expectedBookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException {
|
||||
String jsonString = readFile("/to-java-collection/books.json");
|
||||
List<Book> bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class);
|
||||
assertThat(bookList).size().isEqualTo(3);
|
||||
assertThatExceptionOfType(ClassCastException.class)
|
||||
.isThrownBy(() -> bookList.get(0).getBookId())
|
||||
.withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
|
||||
- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -51,7 +51,6 @@
|
|||
<properties>
|
||||
<dsiutils.version>2.6.0</dsiutils.version>
|
||||
<vavr.version>0.10.2</vavr.version>
|
||||
<commons.version>3.9</commons.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
- [Probability in Java](https://www.baeldung.com/java-probability)
|
||||
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
|
||||
- [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -45,7 +45,6 @@
|
|||
|
||||
<properties>
|
||||
<vavr.version>0.10.2</vavr.version>
|
||||
<commons.version>3.9</commons.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
<org.apache.httpcomponents.version>4.5.3</org.apache.httpcomponents.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
<assertj.version>3.9.1</assertj.version>
|
||||
<commons-fileupload.version>1.3.3</commons-fileupload.version>
|
||||
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<awaitility.version>2.0.0</awaitility.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-lang.version>3.5</commons-lang.version>
|
||||
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||
<hibernate.version>5.2.8.Final</hibernate.version>
|
||||
|
@ -267,7 +265,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<awaitility.version>2.0.0</awaitility.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-lang.version>3.5</commons-lang.version>
|
||||
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||
<hibernate.version>5.2.8.Final</hibernate.version>
|
||||
|
@ -266,7 +264,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
<awaitility.version>2.0.0</awaitility.version>
|
||||
<cassandra-driver.version>3.6.0</cassandra-driver.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-lang.version>3.5</commons-lang.version>
|
||||
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
||||
<hazelcast-hibernate52.version>1.2</hazelcast-hibernate52.version>
|
||||
|
@ -299,7 +297,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang.version}</version>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
|
@ -887,8 +887,6 @@
|
|||
<argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<awaitility.version>2.0.0</awaitility.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-lang.version>3.5</commons-lang.version>
|
||||
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
|
||||
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
|
||||
<gatling-maven-plugin.version>2.2.1</gatling-maven-plugin.version>
|
||||
|
|
|
@ -114,7 +114,6 @@
|
|||
<jsoniter.version>0.9.23</jsoniter.version>
|
||||
<assertj-core.version>3.11.1</assertj-core.version>
|
||||
<moshi.version>1.9.2</moshi.version>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
</properties>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commonsio.version}</version>
|
||||
<version>${commons-io.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -157,7 +157,6 @@
|
|||
<protonpack.version>1.15</protonpack.version>
|
||||
<commons-net.version>3.6</commons-net.version>
|
||||
<assertj.version>3.6.2</assertj.version>
|
||||
<commonsio.version>2.6</commonsio.version>
|
||||
<renjin.version>RELEASE</renjin.version>
|
||||
<rcaller.version>3.0</rcaller.version>
|
||||
<rserve.version>1.8.1</rserve.version>
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.6</commons-lang3.version>
|
||||
<commons-text.version>1.1</commons-text.version>
|
||||
<commons-beanutils.version>1.9.3</commons-beanutils.version>
|
||||
<commons-chain.version>1.2</commons-chain.version>
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
<version>${commons-io.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -165,7 +165,6 @@
|
|||
<properties>
|
||||
<assembly.plugin.version>2.3</assembly.plugin.version>
|
||||
<commons.cli.version>1.2</commons.cli.version>
|
||||
<commons.io.version>2.1</commons.io.version>
|
||||
<httpclient.version>3.0.1</httpclient.version>
|
||||
<storm.version>1.2.2</storm.version>
|
||||
<kafka.version>1.0.0</kafka.version>
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
<commons-compress-version>1.15</commons-compress-version>
|
||||
<commons-io.version>2.3</commons-io.version>
|
||||
<commons-collections4.version>4.0</commons-collections4.version>
|
||||
<commons-lang3.version>3.0</commons-lang3.version>
|
||||
<commons-beanutils.version>1.9.1</commons-beanutils.version>
|
||||
<versions.plugin.version>2.7</versions.plugin.version>
|
||||
</properties>
|
||||
|
|
|
@ -74,8 +74,8 @@
|
|||
<commons.io.version>2.3</commons.io.version>
|
||||
<versions.plugin.version>2.7</versions.plugin.version>
|
||||
<commons.beanutils.version>1.9.1</commons.beanutils.version>
|
||||
<commons.lang3.version>3.0</commons.lang3.version>
|
||||
<commons.collections4.version>4.0</commons.collections4.version>
|
||||
<commons.lang3.version>3.11</commons.lang3.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -27,7 +27,7 @@
|
|||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
|
@ -43,7 +43,6 @@
|
|||
|
||||
<properties>
|
||||
<guava.version>29.0-jre</guava.version>
|
||||
<commons.io.version>2.6</commons.io.version>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
<modelmapper.version>2.3.7</modelmapper.version>
|
||||
<hamcrest.version>2.2</hamcrest.version>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Clean Architecture with Spring Boot](https://www.baeldung.com/spring-boot-clean-architecture)
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>clean-architecture</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>clean-architecture</name>
|
||||
<description>Project for clean architecture in java</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-engine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.pattern.cleanarchitecture;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CleanArchitectureApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CleanArchitectureApplication.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanFactoryPostProcessor beanFactoryPostProcessor(ApplicationContext beanRegistry) {
|
||||
return beanFactory -> {
|
||||
genericApplicationContext((BeanDefinitionRegistry) ((AnnotationConfigServletWebServerApplicationContext) beanRegistry).getBeanFactory());
|
||||
};
|
||||
}
|
||||
|
||||
void genericApplicationContext(BeanDefinitionRegistry beanRegistry) {
|
||||
ClassPathBeanDefinitionScanner beanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanRegistry);
|
||||
beanDefinitionScanner.addIncludeFilter(removeModelAndEntitiesFilter());
|
||||
beanDefinitionScanner.scan("com.baeldung.pattern.cleanarchitecture");
|
||||
}
|
||||
|
||||
static TypeFilter removeModelAndEntitiesFilter() {
|
||||
return (MetadataReader mr, MetadataReaderFactory mrf) -> !mr.getClassMetadata()
|
||||
.getClassName()
|
||||
.endsWith("Model");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
class CommonUser implements User {
|
||||
|
||||
String name;
|
||||
String password;
|
||||
|
||||
CommonUser(String name, String password) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
CommonUser() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passwordIsValid() {
|
||||
return password != null && password.length() > 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
class CommonUserFactory implements UserFactory {
|
||||
@Override
|
||||
public User create(String name, String password) {
|
||||
return new CommonUser(name, password);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
class JpaUser implements UserRegisterDsGateway {
|
||||
|
||||
final JpaUserRepository repository;
|
||||
|
||||
JpaUser(JpaUserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByName(String name) {
|
||||
return repository.existsById(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(UserDsRequestModel requestModel) {
|
||||
UserDataMapper accountDataMapper = new UserDataMapper(requestModel.getName(), requestModel.getPassword(), requestModel.getCreationTime());
|
||||
repository.save(accountDataMapper);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
interface JpaUserRepository extends JpaRepository<UserDataMapper, String> {
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
interface User {
|
||||
boolean passwordIsValid();
|
||||
|
||||
String getName();
|
||||
|
||||
String getPassword();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user")
|
||||
class UserDataMapper {
|
||||
|
||||
@Id
|
||||
String name;
|
||||
|
||||
String password;
|
||||
|
||||
LocalDateTime creationTime;
|
||||
|
||||
public UserDataMapper() {
|
||||
}
|
||||
|
||||
public UserDataMapper(String name, String password, LocalDateTime creationTime) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
public void setCreationTime(LocalDateTime creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
class UserDsRequestModel {
|
||||
|
||||
String name;
|
||||
String password;
|
||||
LocalDateTime creationTime;
|
||||
|
||||
public UserDsRequestModel(String name, String password, LocalDateTime creationTime) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
public void setCreationTime(LocalDateTime creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
interface UserFactory {
|
||||
User create(String name, String password);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
public interface UserInputBoundary {
|
||||
UserResponseModel create(UserRequestModel requestModel);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
interface UserPresenter {
|
||||
UserResponseModel prepareSuccessView(UserResponseModel user);
|
||||
|
||||
UserResponseModel prepareFailView(String error);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
class UserRegisterController {
|
||||
|
||||
final UserInputBoundary userInput;
|
||||
|
||||
UserRegisterController(UserInputBoundary accountGateway) {
|
||||
this.userInput = accountGateway;
|
||||
}
|
||||
|
||||
@PostMapping("/user")
|
||||
UserResponseModel create(@RequestBody UserRequestModel requestModel) {
|
||||
return userInput.create(requestModel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
interface UserRegisterDsGateway {
|
||||
boolean existsByName(String identifier);
|
||||
|
||||
void save(UserDsRequestModel requestModel);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
class UserRegisterInteractor implements UserInputBoundary {
|
||||
|
||||
final UserRegisterDsGateway userDsGateway;
|
||||
final UserPresenter userPresenter;
|
||||
final UserFactory userFactory;
|
||||
|
||||
UserRegisterInteractor(UserRegisterDsGateway userRegisterDfGateway, UserPresenter userPresenter,
|
||||
UserFactory userFactory) {
|
||||
this.userDsGateway = userRegisterDfGateway;
|
||||
this.userPresenter = userPresenter;
|
||||
this.userFactory = userFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserResponseModel create(UserRequestModel requestModel) {
|
||||
if (userDsGateway.existsByName(requestModel.getName())) {
|
||||
return userPresenter.prepareFailView("User already exists.");
|
||||
}
|
||||
User user = userFactory.create(requestModel.getName(), requestModel.getPassword());
|
||||
if (!user.passwordIsValid()) {
|
||||
return userPresenter.prepareFailView("User password must have more than 5 characters.");
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
UserDsRequestModel userDsModel = new UserDsRequestModel(user.getName(), user.getPassword(), now);
|
||||
|
||||
userDsGateway.save(userDsModel);
|
||||
|
||||
UserResponseModel accountResponseModel = new UserResponseModel(user.getName(), now.toString());
|
||||
return userPresenter.prepareSuccessView(accountResponseModel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
class UserRequestModel {
|
||||
|
||||
String name;
|
||||
String password;
|
||||
|
||||
public UserRequestModel() {
|
||||
super();
|
||||
}
|
||||
|
||||
UserRequestModel(String name, String password) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
class UserResponseFormatter implements UserPresenter {
|
||||
|
||||
@Override
|
||||
public UserResponseModel prepareSuccessView(UserResponseModel response) {
|
||||
LocalDateTime responseTime = LocalDateTime.parse(response.getCreationTime());
|
||||
response.setCreationTime(responseTime.format(DateTimeFormatter.ofPattern("hh:mm:ss")));
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserResponseModel prepareFailView(String error) {
|
||||
throw new ResponseStatusException(HttpStatus.CONFLICT, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
public class UserResponseModel {
|
||||
|
||||
String login;
|
||||
String creationTime;
|
||||
|
||||
public UserResponseModel(String login, String creationTime) {
|
||||
this.login = login;
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public String getCreationTime() {
|
||||
return creationTime;
|
||||
}
|
||||
|
||||
public void setCreationTime(String creationTime) {
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
server.port=8080
|
||||
server.error.include-message=always
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import com.baeldung.pattern.cleanarchitecture.usercreation.UserResponseFormatter;
|
||||
import com.baeldung.pattern.cleanarchitecture.usercreation.UserResponseModel;
|
||||
|
||||
class UserResponseFormatterUnitTest {
|
||||
|
||||
UserResponseFormatter userResponseFormatter = new UserResponseFormatter();
|
||||
|
||||
@Test
|
||||
void givenDateAnd3HourTime_whenPrepareSuccessView_thenReturnOnly3HourTime() {
|
||||
UserResponseModel modelResponse = new UserResponseModel("baeldung", "2020-12-20T03:00:00.000");
|
||||
UserResponseModel formattedResponse = userResponseFormatter.prepareSuccessView(modelResponse);
|
||||
|
||||
assertThat(formattedResponse.getCreationTime()).isEqualTo("03:00:00");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrepareFailView_thenThrowHttpConflictException() {
|
||||
assertThatThrownBy(() -> userResponseFormatter.prepareFailView("Invalid password"))
|
||||
.isInstanceOf(ResponseStatusException.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.pattern.cleanarchitecture.usercreation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class UserUnitTest {
|
||||
|
||||
@Test
|
||||
void given123Password_whenPasswordIsNotValid_thenIsFalse() {
|
||||
User user = new CommonUser("Baeldung", "123");
|
||||
|
||||
assertThat(user.passwordIsValid()).isFalse();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
<module>hexagonal-architecture</module>
|
||||
<module>intercepting-filter</module>
|
||||
<module>solid</module>
|
||||
<module>clean-architecture</module>
|
||||
</modules>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue