Merge branch 'eugenp:master' into master

This commit is contained in:
cesarevalenti90 2023-01-19 09:49:36 +01:00 committed by GitHub
commit 1bdb77da2b
168 changed files with 4095 additions and 292 deletions

View File

@ -1,36 +1,41 @@
package com.baeldung.httpclient.cookies;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.ClientCookie;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.Cookie;
import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.impl.classic.BasicHttpClientResponseHandler;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
public class HttpClientGettingCookieValueUnitTest {
class HttpClientGettingCookieValueUnitTest {
private static Logger log = LoggerFactory.getLogger(HttpClientGettingCookieValueUnitTest.class);
private static final String SAMPLE_URL = "http://www.baeldung.com/";
@Test
public final void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
void whenSettingCustomCookieOnTheRequest_thenGettingTheSameCookieFromTheResponse() throws IOException {
HttpClientContext context = HttpClientContext.create();
context.setAttribute(HttpClientContext.COOKIE_STORE, createCustomCookieStore());
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
try (CloseableHttpResponse response = httpClient.execute(new HttpGet(SAMPLE_URL), context)) {
final HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient client = HttpClientBuilder.create()
.build()) {
client.execute(request, context, new BasicHttpClientResponseHandler());
CookieStore cookieStore = context.getCookieStore();
Cookie customCookie = cookieStore.getCookies()
.stream()
@ -42,13 +47,12 @@ public class HttpClientGettingCookieValueUnitTest {
assertEquals("test_value", customCookie.getValue());
}
}
}
private BasicCookieStore createCustomCookieStore() {
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value");
cookie.setDomain("baeldung.com");
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");
cookie.setAttribute("domain", "true");
cookie.setPath("/");
cookieStore.addCookie(cookie);
return cookieStore;

View File

@ -0,0 +1,2 @@
## Relevant Articles
- [Record Patterns in Java 19](https://www.baeldung.com/java-19-record-patterns)

View File

@ -0,0 +1,82 @@
package com.baeldung.monad;
import java.util.Optional;
import java.util.function.Function;
class MonadBaseExample {
public double multiplyBy2(double n) {
return n * 2;
}
public double divideBy2(double n) {
return n / 2;
}
public double add3(double n) {
return n + 3;
}
public double subtract1(double n) {
return n - 1;
}
}
class MonadSample1 extends MonadBaseExample {
public double apply(double n) {
return subtract1(add3(divideBy2(multiplyBy2(multiplyBy2(2)))));
}
}
class MonadSample2 extends MonadBaseExample {
public double apply(double n) {
double n1 = multiplyBy2(n);
double n2 = multiplyBy2(n1);
double n3 = divideBy2(n2);
double n4 = add3(n3);
return subtract1(n4);
}
}
class MonadSample3 extends MonadBaseExample {
public double apply(double n) {
return Optional.of(n)
.flatMap(value -> Optional.of(multiplyBy2(value)))
.flatMap(value -> Optional.of(multiplyBy2(value)))
.flatMap(value -> Optional.of(divideBy2(value)))
.flatMap(value -> Optional.of(add3(value)))
.flatMap(value -> Optional.of(subtract1(value)))
.get();
}
}
class MonadSample4 extends MonadBaseExample {
public boolean leftIdentity() {
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value + 1);
return Optional.of(3).flatMap(mapping).equals(mapping.apply(3));
}
public boolean rightIdentity() {
return Optional.of(3).flatMap(Optional::of).equals(Optional.of(3));
}
public boolean associativity() {
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value + 1);
Optional<Integer> leftSide = Optional.of(3).flatMap(mapping).flatMap(Optional::of);
Optional<Integer> rightSide = Optional.of(3).flatMap(v -> mapping.apply(v).flatMap(Optional::of));
return leftSide.equals(rightSide);
}
}
class MonadSample5 extends MonadBaseExample {
public boolean fail() {
Function<Integer, Optional<Integer>> mapping = value -> Optional.of(value == null ? -1 : value + 1);
return Optional.ofNullable((Integer) null).flatMap(mapping).equals(mapping.apply(null));
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.monad;
import org.junit.Assert;
import org.junit.Test;
public class MonadSampleUnitTest {
@Test
public void whenNotUsingMonad_shouldBeOk() {
MonadSample1 test = new MonadSample1();
Assert.assertEquals(6.0, test.apply(2), 0.000);
}
@Test
public void whenNotUsingMonadButUsingTempVars_shouldBeOk() {
MonadSample2 test = new MonadSample2();
Assert.assertEquals(6.0, test.apply(2), 0.000);
}
@Test
public void whenUsingMonad_shouldBeOk() {
MonadSample3 test = new MonadSample3();
Assert.assertEquals(6.0, test.apply(2), 0.000);
}
@Test
public void whenTestingMonadProperties_shouldBeOk() {
MonadSample4 test = new MonadSample4();
Assert.assertEquals(true, test.leftIdentity());
Assert.assertEquals(true, test.rightIdentity());
Assert.assertEquals(true, test.associativity());
}
@Test
public void whenBreakingMonadProperties_shouldBeFalse() {
MonadSample5 test = new MonadSample5();
Assert.assertEquals(false, test.fail());
}
}

View File

@ -6,3 +6,4 @@ This module contains articles about arrays conversion in Java
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)
- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array)
- [Convert a Byte Array to a Numeric Representation in Java](https://www.baeldung.com/java-byte-array-to-number)
- [Converting a String Array Into an int Array in Java](https://www.baeldung.com/java-convert-string-array-to-int-array)

View File

@ -13,3 +13,4 @@
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
- [Differences Between Iterator and Iterable and How to Use Them?](https://www.baeldung.com/java-iterator-vs-iterable)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-1) [[next -->]](/core-java-modules/core-java-collections-3)

View File

@ -7,7 +7,6 @@
- [ArrayList vs. LinkedList vs. HashMap in Java](https://www.baeldung.com/java-arraylist-vs-linkedlist-vs-hashmap)
- [Java Deque vs. Stack](https://www.baeldung.com/java-deque-vs-stack)
- [Collection.toArray(new T[0]) or .toArray(new T[size])](https://www.baeldung.com/java-collection-toarray-methods)
- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map)
- [Sorting Objects in a List by Date](https://www.baeldung.com/java-sort-list-by-date)
- [Fixed Size Queue Implementations in Java](https://www.baeldung.com/java-fixed-size-queue)
- [Difference Between Java Enumeration and Iterator](https://www.baeldung.com/java-enumeration-vs-iterator)
@ -15,4 +14,4 @@
- [Guide to Java PriorityQueue](https://www.baeldung.com/java-priorityqueue)
- [Java Generics PECS Producer Extends Consumer Super](https://www.baeldung.com/java-generics-pecs)
- [Reversing a Stack in Java](https://www.baeldung.com/java-reversing-a-stack)
- [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-3)

View File

@ -25,6 +25,12 @@
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>

View File

@ -2,9 +2,7 @@ package com.baeldung.collections.comparation;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -2,10 +2,8 @@ package com.baeldung.collections.comparation;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -10,7 +10,7 @@ import java.util.Date;
import java.util.List;
import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class EmployeeSortingByDateUnitTest {

View File

@ -5,8 +5,9 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ComparatorsUnitTest {
@Test

View File

@ -1,10 +1,12 @@
package com.baeldung.stackreversal;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.baeldung.collections.sorting.Employee;
import com.baeldung.collections.stackreversal.ReverseStackUsingQueue;
import com.baeldung.collections.stackreversal.ReverseStackUsingRecursion;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.util.*;
import java.util.stream.Collectors;
@ -15,7 +17,7 @@ public class StackReversalUnitTest {
ReverseStackUsingQueue reverseStack = new ReverseStackUsingQueue();
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
Stack<Integer> reverseList = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
Assert.assertEquals(reverseStack.reverseIntegerStack(originalStack), reverseList);
assertEquals(reverseStack.reverseIntegerStack(originalStack), reverseList);
}
@Test
@ -26,7 +28,7 @@ public class StackReversalUnitTest {
Collections.reverse(listOfWordsReversed);
Stack<String> originalStack = generateStackFromGivenList(listOfWords, new Stack<String>());
Stack<String> reversedStack = generateStackFromGivenList(listOfWordsReversed, new Stack<String>());
Assert.assertEquals(stackReversal.reverseStringStack(originalStack), reversedStack);
assertEquals(stackReversal.reverseStringStack(originalStack), reversedStack);
}
@Test
@ -43,7 +45,7 @@ public class StackReversalUnitTest {
Collections.reverse(employeeReversed);
Stack<Employee> originalStack = generateStackFromGivenList(employeeList, new Stack<Employee>());
Stack<Employee> reverseStack = generateStackFromGivenList(employeeReversed, new Stack<Employee>());
Assert.assertEquals(stackReversal.reverseEmployeeStack(originalStack), reverseStack);
assertEquals(stackReversal.reverseEmployeeStack(originalStack), reverseStack);
}
@Test
@ -51,7 +53,7 @@ public class StackReversalUnitTest {
ReverseStackUsingRecursion reverseStack = new ReverseStackUsingRecursion();
Stack<Integer> originalStack = generateStackFromGivenList(Arrays.stream(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).boxed().collect(Collectors.toList()), new Stack<Integer>());
Stack<Integer> reversedStack = generateStackFromGivenList(Arrays.stream(new int[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}).boxed().collect(Collectors.toList()), new Stack<Integer>());
Assert.assertEquals(reverseStack.reverseIntegerStack(originalStack), reversedStack);
assertEquals(reverseStack.reverseIntegerStack(originalStack), reversedStack);
}
private Stack generateStackFromGivenList(List elements, Stack stack){

View File

@ -5,6 +5,33 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-collections-array-list</artifactId>
<version>0.1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven-compiler-plugin.source}</source>
<target>${maven-compiler-plugin.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.plugin.version}</version>
<configuration>
<argLine>
--add-opens java.base/java.util=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven-compiler-plugin.source>16</maven-compiler-plugin.source>
<maven-compiler-plugin.target>16</maven-compiler-plugin.target>
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
</properties>
<name>core-java-collections-array-list</name>
<packaging>jar</packaging>
@ -20,6 +47,12 @@
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package com.baeldung.list.ignorecase;
import java.util.List;
public class IgnoreCaseSearchUtil {
public static boolean ignoreCaseContains(List<String> theList, String searchStr) {
for (String s : theList) {
if (searchStr.equalsIgnoreCase(s)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.list.ignorecase;
import java.util.ArrayList;
import java.util.Collection;
public class IgnoreCaseStringList extends ArrayList<String> {
public IgnoreCaseStringList() {
}
public IgnoreCaseStringList(Collection<? extends String> c) {
super(c);
}
@Override
public boolean contains(Object o) {
String searchStr = (String) o;
// Using Stream API:
// return this.stream().anyMatch(searchStr::equalsIgnoreCase);
for (String s : this) {
if (searchStr.equalsIgnoreCase(s)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.listofobjectstolistofstring;
public class Node {
private final int x;
private final int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Node (" + "x=" + x + ", y=" + y + ')';
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.listofobjectstolistofstring;
public class User {
private final String fullName;
public User(String fullName) {
this.fullName = fullName;
}
@Override
public String toString() {
return "User (" + "full name='" + fullName + ')';
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.triple;
public class Triple<L, M, R> {
private final L left;
private final M middle;
private final R right;
public Triple(L left, M middle, R right) {
this.left = left;
this.middle = middle;
this.right = right;
}
public L getLeft() {
return left;
}
public M getMiddle() {
return middle;
}
public R getRight() {
return right;
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.list.ignorecase;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class IgnoreCaseContainsUnitTest {
private static final List<String> LANGUAGES = Arrays.asList("Java", "Python", "Kotlin", "Ruby", "Javascript", "Go");
@Test
void givenStringList_whenCallTheStandardContains_shouldReturnFalse() {
String searchStr = "jAvA";
boolean result = LANGUAGES.contains(searchStr);
assertFalse(result);
}
@Test
void givenStringList_whenSearchIgnoreCaseUsingStreamAPI_shouldReturnTrue() {
String searchStr = "koTliN";
boolean result = LANGUAGES.stream().anyMatch(searchStr::equalsIgnoreCase);
assertTrue(result);
}
@Test
void givenStringList_whenUsingUtilClass_shouldReturnTrue() {
String searchStr = "ruBY";
boolean result = IgnoreCaseSearchUtil.ignoreCaseContains(LANGUAGES, searchStr);
assertTrue(result);
}
@Test
void givenStringList_whenUsingIgnoreCaseStringList_shouldReturnTrue() {
String searchStr = "pYtHoN";
List<String> ignoreCaseList = new IgnoreCaseStringList(LANGUAGES);
boolean result = ignoreCaseList.contains(searchStr);
assertTrue(result);
boolean resultContainAll = ignoreCaseList.containsAll(Arrays.asList("pYtHon", "jAvA", "koTliN", "ruBY"));
assertTrue(resultContainAll);
}
}

View File

@ -0,0 +1,92 @@
package com.baeldung.listofobjectstolistofstring;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class ConvertObjectListToStringListUnitTest {
@Test
public void givenObjectList_whenForEachUsedToConvert_thenReturnSuccess() {
List<String> outputList = new ArrayList<>(objectListWithNull().size());
for (Object obj : objectListWithNull()) {
outputList.add(Objects.toString(obj, null));
}
Assert.assertEquals(expectedStringListWithNull(), outputList);
}
@Test
public void givenObjectList_whenUsingStreamsToConvert_thenReturnSuccess() {
List<String> outputList;
outputList = objectListWithNull().stream()
.map((obj) -> Objects.toString(obj, null))
.collect(Collectors.toList());
Assert.assertEquals(expectedStringListWithNull(), outputList);
}
@Test
public void givenObjectList_whenUsingStreamsUnmodifiableListToConvert_thenReturnSuccess() {
List<String> outputList;
outputList = objectListWithNull().stream()
.filter(Objects::nonNull)
.map((obj) -> Objects.toString(obj, null))
.collect(Collectors.toUnmodifiableList());
Assert.assertEquals(expectedStringListWithoutNull(), outputList);
}
@Test
public void givenObjectList_whenUsingGuavaTransform_thenReturnSuccess() {
List<String> outputList;
outputList = Lists.transform(objectListWithNull(), obj -> Objects.toString(obj, null));
Assert.assertEquals(expectedStringListWithNull(), outputList);
}
@Test
public void givenObjectListWithNoNull_whenUsingToList_thenReturnSuccess() {
List<String> outputList;
outputList = objectListWithoutNull().stream()
.map((obj) -> Objects.toString(obj, null))
.toList();
Assert.assertEquals(expectedStringListWithoutNull(), outputList);
}
private List<String> expectedStringListWithNull() {
List<String> listOfStrings = new ArrayList<>();
listOfStrings.add("1");
listOfStrings.add("true");
listOfStrings.add("hello");
listOfStrings.add(Double.toString(273773.98));
listOfStrings.add(null);
listOfStrings.add(new Node(2, 4).toString());
listOfStrings.add(new User("John Doe").toString());
return listOfStrings;
}
private List<Object> objectListWithNull() {
List<Object> listOfStrings = new ArrayList<>();
listOfStrings.add(1);
listOfStrings.add(true);
listOfStrings.add("hello");
listOfStrings.add(Double.valueOf(273773.98));
listOfStrings.add(null);
listOfStrings.add(new Node(2, 4));
listOfStrings.add(new User("John Doe"));
return listOfStrings;
}
private List<String> expectedStringListWithoutNull() {
return List.of("1", "true", "hello", Double.toString(273773.98), new Node(2, 4).toString(), new User("John Doe").toString());
}
private List<Object> objectListWithoutNull() {
return List.of(1, true, "hello", Double.valueOf(273773.98), new Node(2, 4), new User("John Doe"));
}
}

View File

@ -0,0 +1,105 @@
package com.baeldung.triple;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
public class TripleInListUnitTest {
enum OP {
PLUS("+"), MINUS("-"), MULTIPLY("x");
final String opSign;
OP(String x) {
this.opSign = x;
}
}
private String createQuestion(Long num1, OP operator, Long num2) {
long result;
switch (operator) {
case PLUS:
result = num1 + num2;
break;
case MINUS:
result = num1 - num2;
break;
case MULTIPLY:
result = num1 * num2;
break;
default:
throw new IllegalArgumentException("Unknown operator");
}
return String.format("%d %s %d = ? ( answer: %d )", num1, operator.opSign, num2, result);
}
private static final List<String> EXPECTED_QUESTIONS = Arrays.asList(
"100 - 42 = ? ( answer: 58 )",
"100 + 42 = ? ( answer: 142 )",
"100 x 42 = ? ( answer: 4200 )");
@Test
void givenTripleValues_whenStoreAsList_thenTypeIsNotSafe() {
List myTriple1 = new ArrayList(3);
myTriple1.add(100L);
myTriple1.add(OP.MINUS);
myTriple1.add(42L);
List myTriple2 = new ArrayList(3);
myTriple2.add(100L);
myTriple2.add(OP.PLUS);
myTriple2.add(42L);
List myTriple3 = new ArrayList(3);
myTriple3.add(100L);
myTriple3.add(OP.MULTIPLY);
myTriple3.add(42L);
List<List> listOfTriples = new ArrayList<>(Arrays.asList(myTriple1, myTriple2, myTriple3));
List oopsTriple = new ArrayList(3);
oopsTriple.add("Oops");
oopsTriple.add(911L);
oopsTriple.add("The type is wrong");
listOfTriples.add(oopsTriple);
assertEquals(4, listOfTriples.size());
List<String> questions = listOfTriples.stream()
.filter(
triple -> triple.size() == 3
&& triple.get(0) instanceof Long
&& triple.get(1) instanceof OP
&& triple.get(2) instanceof Long
).map(triple -> {
Long left = (Long) triple.get(0);
OP op = (OP) triple.get(1);
Long right = (Long) triple.get(2);
return createQuestion(left, op, right);
}).collect(Collectors.toList());
assertEquals(EXPECTED_QUESTIONS, questions);
}
@Test
void givenTripleValues_whenUsingTheTripleClass_thenTypeIsSafeAndNeat() {
Triple<Long, OP, Long> triple1 = new Triple<>(100L, OP.MINUS, 42L);
Triple<Long, OP, Long> triple2 = new Triple<>(100L, OP.PLUS, 42L);
Triple<Long, OP, Long> triple3 = new Triple<>(100L, OP.MULTIPLY, 42L);
Triple<String, Long, String> tripleOops = new Triple<>("Oops", 911L, "The type is wrong");
List<Triple<Long, OP, Long>> listOfTriples = new ArrayList<>(Arrays.asList(triple1, triple2, triple3));
// listOfTriples.add(tripleOops); // Compiler error: "java: incompatible types ... "
List<String> questions = listOfTriples.stream()
.map(triple -> createQuestion(triple.getLeft(), triple.getMiddle(), triple.getRight()))
.collect(Collectors.toList());
assertEquals(EXPECTED_QUESTIONS, questions);
}
}

View File

@ -12,4 +12,5 @@ This module contains articles about Map data structures in Java.
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
- [Guide to Apache Commons MultiValuedMap](https://www.baeldung.com/apache-commons-multi-valued-map)
- [The Java HashMap Under the Hood](https://www.baeldung.com/java-hashmap-advanced)
- [Create an Empty Map in Java](https://www.baeldung.com/java-create-empty-map)
- More articles: [[next -->]](/core-java-modules/core-java-collections-maps-2)

View File

@ -20,6 +20,12 @@
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,7 +1,5 @@
package com.baeldung.maps.initialize;
package com.baeldung.map;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -10,6 +8,9 @@ import java.util.NavigableMap;
import java.util.SortedMap;
import java.util.TreeMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
public class EmptyMapInitializer {
public static Map<String, String> articleMap;

View File

@ -1,11 +1,12 @@
package com.baeldung.maps.initialize;
import java.util.Map;
import org.junit.Test;
package com.baeldung.map;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Map;
import org.junit.Test;
public class EmptyMapInitializerUnitTest {
@Test(expected=UnsupportedOperationException.class)

View File

@ -2,3 +2,5 @@
- [Using Streams to Collect Into a TreeSet](https://www.baeldung.com/java-stream-collect-into-treeset)
- [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset)
- [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-set)

View File

@ -15,6 +15,12 @@
</parent>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,4 +1,4 @@
package com.baeldung.collections.sorting;
package com.baeldung.hashset.sorting;
import static org.assertj.core.api.Assertions.assertThat;

View File

@ -13,5 +13,6 @@ This module contains articles about core Java input and output (IO)
- [Generate the MD5 Checksum for a File in Java](https://www.baeldung.com/java-md5-checksum-file)
- [Getting the Filename From a String Containing an Absolute File Path](https://www.baeldung.com/java-filename-full-path)
- [Mocking Java InputStream Object](https://www.baeldung.com/java-mocking-inputstream)
- [PrintStream vs PrintWriter in Java](https://www.baeldung.com/java-printstream-vs-printwriter)
- [[<-- Prev]](/core-java-modules/core-java-io-3)

View File

@ -0,0 +1,6 @@
package com.baeldung.inmemorycompilation;
public interface InMemoryClass {
void runCode();
}

View File

@ -0,0 +1,30 @@
package com.baeldung.inmemorycompilation;
import static java.util.Objects.requireNonNull;
import java.util.Map;
public class InMemoryClassLoader extends ClassLoader {
private final InMemoryFileManager manager;
public InMemoryClassLoader(ClassLoader parent, InMemoryFileManager manager) {
super(parent);
this.manager = requireNonNull(manager, "manager must not be null");
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Map<String, JavaClassAsBytes> compiledClasses = manager
.getBytesMap();
if (compiledClasses.containsKey(name)) {
byte[] bytes = compiledClasses.get(name)
.getBytes();
return defineClass(name, bytes, 0, bytes.length);
} else {
throw new ClassNotFoundException();
}
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.inmemorycompilation;
import java.util.Hashtable;
import java.util.Map;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
public class InMemoryFileManager extends ForwardingJavaFileManager<JavaFileManager> {
private final Map<String, JavaClassAsBytes> compiledClasses;
private final ClassLoader loader;
public InMemoryFileManager(StandardJavaFileManager standardManager) {
super(standardManager);
this.compiledClasses = new Hashtable<>();
this.loader = new InMemoryClassLoader(this.getClass()
.getClassLoader(),
this
);
}
/**
* Used to get the class loader for our compiled class. It creates an anonymous class extending
* the SecureClassLoader which uses the byte code created by the compiler and stored in the
* JavaClassObject, and returns the Class for it
*
* @param location where to place or search for file objects.
*/
@Override
public ClassLoader getClassLoader(Location location) {
return loader;
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind,
FileObject sibling) {
JavaClassAsBytes classAsBytes = new JavaClassAsBytes(
className, kind);
compiledClasses.put(className, classAsBytes);
return classAsBytes;
}
public Map<String, JavaClassAsBytes> getBytesMap() {
return compiledClasses;
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.inmemorycompilation;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
/**
* Represents a Java class file (compiled byte-code)
*/
public class JavaClassAsBytes extends SimpleJavaFileObject {
protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
public JavaClassAsBytes(String name, Kind kind) {
super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);
}
public byte[] getBytes() {
return bos.toByteArray();
}
@Override
public OutputStream openOutputStream() {
return bos;
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.inmemorycompilation;
import static java.util.Objects.requireNonNull;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
/**
* Represents a Java source code file
*/
public class JavaSourceFromString extends SimpleJavaFileObject {
private final String sourceCode;
public JavaSourceFromString(String name, String sourceCode) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
Kind.SOURCE
);
this.sourceCode = requireNonNull(sourceCode, "sourceCode must not be null");
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return sourceCode;
}
}

View File

@ -0,0 +1,57 @@
package com.baeldung.inmemorycompilation;
import java.util.Collections;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class InMemoryCompilationUnitTest {
private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryCompilationUnitTest.class);
final static String QUALIFIED_CLASS_NAME = "com.baeldung.inmemorycompilation.TestClass";
final static String SOURCE_CODE =
"package com.baeldung.inmemorycompilation;\n"
+ "public class TestClass implements InMemoryClass {\n"
+ "@Override\n"
+ " public void runCode() {\n"
+ " System.out.println(\"code is running...\");\n"
+ " }\n"
+ "}\n";
@Test
public void whenStringIsCompiled_ThenCodeShouldExecute() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
InMemoryFileManager manager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null));
List<JavaFileObject> sourceFiles = Collections.singletonList(new JavaSourceFromString(QUALIFIED_CLASS_NAME, SOURCE_CODE));
JavaCompiler.CompilationTask task = compiler.getTask(null, manager, diagnostics, null, null, sourceFiles);
boolean result = task.call();
if (result) {
diagnostics.getDiagnostics()
.forEach(d -> LOGGER.error(String.valueOf(d)));
} else {
ClassLoader classLoader = manager.getClassLoader(null);
Class<?> clazz = classLoader.loadClass(QUALIFIED_CLASS_NAME);
InMemoryClass instanceOfClass = (InMemoryClass) clazz.newInstance();
Assertions.assertInstanceOf(InMemoryClass.class, instanceOfClass);
instanceOfClass.runCode();
}
}
}

View File

@ -1,10 +1,12 @@
package com.baeldung.resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.net.URL;
@Disabled
class ClassGetResourceUnitTest {
@Test

View File

@ -1,10 +1,12 @@
package com.baeldung.resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.net.URL;
@Disabled
class ClassLoaderGetResourceUnitTest {
@Test

View File

@ -13,4 +13,12 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,30 @@
package com.baeldung.nullchecking;
import java.util.Objects;
import java.util.stream.Stream;
public class Car {
Integer power;
Integer year;
public boolean allNull() {
if (power != null) {
return false;
}
if (year != null) {
return false;
}
return true;
}
public boolean allNullV2() {
return Stream.of(power, year)
.allMatch(Objects::isNull);
}
}

View File

@ -0,0 +1,25 @@
package com.baeldung.nullchecking;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;
public class NullChecker {
public static boolean allNull(Object target) {
return Arrays.stream(target.getClass()
.getDeclaredFields())
.peek(f -> f.setAccessible(true))
.map(f -> getFieldValue(f, target))
.allMatch(Objects::isNull);
}
private static Object getFieldValue(Field field, Object target) {
try {
return field.get(target);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,45 @@
package com.baeldung.nullchecking;
import org.apache.commons.lang3.ObjectUtils;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class NullCheckUnitTest {
@Test
public void givenNullFields_whenCheckForNullsUsingIfs_thenReturnCorrectValue(){
Car car = new Car();
boolean result = car.allNull();
assertTrue(result);
}
@Test
public void givenNullFields_whenCheckForNullsUsingStreams_thenReturnCorrectValue(){
Car car = new Car();
boolean result = car.allNullV2();
assertTrue(result);
}
@Test
public void givenNullFields_whenCheckForNullsUsingApacheCommons_thenReturnCorrectValue(){
Car car = new Car();
boolean result = ObjectUtils.allNull(car.power, car.year);
assertTrue(result);
}
@Test
public void givenNullFields_whenCheckForNullsUsingReflection_thenReturnCorrectValue(){
Car car = new Car();
boolean result = NullChecker.allNull(car);
assertTrue(result);
}
}

View File

@ -7,3 +7,4 @@
- [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies)
- [What Causes java.lang.reflect.InvocationTargetException?](https://www.baeldung.com/java-lang-reflect-invocationtargetexception)
- [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method)
- [Getting Class Type From a String in Java](https://www.baeldung.com/java-get-class-object-from-string)

View File

@ -11,4 +11,5 @@ This module contains articles about core Java Security
- [Generating a Secure AES Key in Java](https://www.baeldung.com/java-secure-aes-key)
- [Computing an X509 Certificates Thumbprint in Java](https://www.baeldung.com/java-x509-certificate-thumbprint)
- [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty)
- [Common Exceptions of Crypto APIs in Java](https://www.baeldung.com/java-crypto-apis-exceptions)
- More articles: [[<-- prev]](/core-java-modules/core-java-security-2)

View File

@ -59,6 +59,36 @@
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava3</groupId>
<artifactId>rxjava</artifactId>
<version>${rx.java3.version}</version>
</dependency>
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>${io.varv.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${io.reactor3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${apache.commons.collection4.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google.guava.version}</version>
</dependency>
<dependency>
<groupId>com.oath.cyclops</groupId>
<artifactId>cyclops</artifactId>
<version>${cyclops.version}</version>
</dependency>
</dependencies>
<build>
@ -90,6 +120,12 @@
<maven.compiler.target>12</maven.compiler.target>
<rx.java.version>1.2.5</rx.java.version>
<rx.java2.version>2.2.2</rx.java2.version>
<rx.java3.version>3.1.5</rx.java3.version>
<io.varv.version>1.0.0-alpha-4</io.varv.version>
<io.reactor3.version>3.5.1</io.reactor3.version>
<apache.commons.collection4.version>4.4</apache.commons.collection4.version>
<google.guava.version>31.1-jre</google.guava.version>
<cyclops.version>10.4.1</cyclops.version>
</properties>
</project>

View File

@ -0,0 +1,47 @@
package com.baeldung.streams.processing;
import static java.util.Spliterator.ORDERED;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class CustomBatchIterator<T> implements Iterator<List<T>> {
private final int batchSize;
private List<T> currentBatch;
private final Iterator<T> iterator;
public CustomBatchIterator(Iterator<T> sourceIterator, int batchSize) {
this.batchSize = batchSize;
this.iterator = sourceIterator;
}
@Override
public List<T> next() {
return currentBatch;
}
@Override
public boolean hasNext() {
prepareNextBatch();
return currentBatch != null && !currentBatch.isEmpty();
}
public static <T> Stream<List<T>> batchStreamOf(Stream<T> stream, int batchSize) {
return stream(new CustomBatchIterator<>(stream.iterator(), batchSize));
}
private static <T> Stream<T> stream(Iterator<T> iterator) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, ORDERED), false);
}
private void prepareNextBatch() {
currentBatch = new ArrayList<>(batchSize);
while (iterator.hasNext() && currentBatch.size() < batchSize) {
currentBatch.add(iterator.next());
}
}
}

View File

@ -0,0 +1,141 @@
package com.baeldung.streams.processing;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.apache.commons.collections4.ListUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.google.common.collect.Iterators;
import cyclops.data.LazySeq;
import cyclops.reactive.ReactiveSeq;
import io.reactivex.rxjava3.core.Observable;
import reactor.core.publisher.Flux;
public class StreamProcessingUnitTest {
public final int BATCH_SIZE = 10;
private final List<Integer> firstBatch = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
private final List<Integer> secondBatch = List.of(10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
private final List<Integer> thirdBatch = List.of(20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
private final List<Integer> fourthBatch = List.of(30, 31, 32, 33);
public Stream<Integer> data;
@BeforeEach
public void setUp() {
data = IntStream.range(0, 34)
.boxed();
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingSpliterator_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>();
CustomBatchIterator.batchStreamOf(data, BATCH_SIZE)
.forEach(result::add);
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingCollectionAPI_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = data.collect(Collectors.groupingBy(it -> it / BATCH_SIZE))
.values();
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchParallelUsingCollectionAPI_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = data.parallel()
.collect(Collectors.groupingBy(it -> it / BATCH_SIZE))
.values();
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingRxJavaV3_thenFourBatchesAreObtained() {
// RxJava v3
Collection<List<Integer>> result = new ArrayList<>();
Observable.fromStream(data)
.buffer(BATCH_SIZE)
.subscribe(result::add);
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingReactor_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>();
Flux.fromStream(data)
.buffer(BATCH_SIZE)
.subscribe(result::add);
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingApacheCommon_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>(ListUtils.partition(data.collect(Collectors.toList()), BATCH_SIZE));
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingGuava_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>();
Iterators.partition(data.iterator(), BATCH_SIZE)
.forEachRemaining(result::add);
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingCyclops_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>();
ReactiveSeq.fromStream(data)
.grouped(BATCH_SIZE)
.toList()
.forEach(value -> result.add(value.collect(Collectors.toList())));
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingCyclopsLazy_thenFourBatchesAreObtained() {
Collection<List<Integer>> result = new ArrayList<>();
LazySeq.fromStream(data)
.grouped(BATCH_SIZE)
.toList()
.forEach(value -> result.add(value.collect(Collectors.toList())));
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.streams.processing.vavr;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import com.baeldung.streams.processing.StreamProcessingUnitTest;
import io.vavr.collection.List;
import io.vavr.collection.Stream;
public class StreamProcessingWithVavrUnitTest extends StreamProcessingUnitTest {
private final List<Integer> firstBatch = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
private final List<Integer> secondBatch = List.of(10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
private final List<Integer> thirdBatch = List.of(20, 21, 22, 23, 24, 25, 26, 27, 28, 29);
private final List<Integer> fourthBatch = List.of(30, 31, 32, 33);
@Test
public void givenAStreamOfData_whenIsProcessingInBatchUsingVavr_thenFourBatchesAreObtained() {
List<List<Integer>> result = Stream.ofAll(data)
.toList()
.grouped(BATCH_SIZE)
.toList();
assertTrue(result.contains(firstBatch));
assertTrue(result.contains(secondBatch));
assertTrue(result.contains(thirdBatch));
assertTrue(result.contains(fourthBatch));
}
}

View File

@ -27,17 +27,17 @@ public final class UUIDGenerator {
private static long get64LeastSignificantBitsForVersion1() {
final long random63BitLong = new Random().nextLong() & 0x3FFFFFFFFFFFFFFFL;
final long variant3BitFlag = 0x8000000000000000L;
return random63BitLong + variant3BitFlag;
long variant3BitFlag = 0x8000000000000000L;
return random63BitLong | variant3BitFlag;
}
private static long get64MostSignificantBitsForVersion1() {
final long timeForUuidIn100Nanos = System.currentTimeMillis();
final long time_low = (timeForUuidIn100Nanos & 0x0000_0000_FFFF_FFFFL) << 32;
final long time_mid = ((timeForUuidIn100Nanos >> 32) & 0xFFFF) << 16;
final long currentTimeMillis = System.currentTimeMillis();
final long time_low = (currentTimeMillis & 0x0000_0000_FFFF_FFFFL) << 32;
final long time_mid = ((currentTimeMillis >> 32) & 0xFFFF) << 16;
final long version = 1 << 12;
final long time_hi = ((timeForUuidIn100Nanos >> 48) & 0x0FFF);
return time_low + time_mid + version + time_hi;
final long time_high = ((currentTimeMillis >> 48) & 0x0FFF);
return time_low | time_mid | version | time_high;
}
/**

View File

@ -31,7 +31,6 @@
<module>core-java-collections-2</module>
<module>core-java-collections-3</module>
<module>core-java-collections-4</module>
<module>core-java-collections-array-list</module>
<module>core-java-collections-conversions</module>
<module>core-java-collections-conversions-2</module>
<module>core-java-collections-set-2</module>

View File

@ -2,6 +2,7 @@ package com.baeldung.gcp.firebase.publisher.controller;
import java.util.List;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
@ -103,7 +104,7 @@ public class FirebasePublisherController {
@DeleteMapping("/subscriptions/{topic}/{registrationToken}")
public ResponseEntity<Void> deleteSubscription(@PathVariable String topic, @PathVariable String registrationToken) throws FirebaseMessagingException {
fcm.subscribeToTopic(List.of(registrationToken), topic);
fcm.subscribeToTopic(Arrays.asList(registrationToken), topic);
return ResponseEntity.ok().build();
}
}

View File

@ -2,3 +2,4 @@
### Relevant Articles:
- [How to Configure Conditional Dependencies in Gradle](https://www.baeldung.com/gradle-conditional-dependencies)
- [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories)

View File

@ -1,72 +1,77 @@
package com.baeldung.httpclient.base;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import com.baeldung.httpclient.ResponseUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.handler.CustomHttpClientResponseHandler;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ParseException;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
public class HttpClientBasicLiveTest {
private static final String SAMPLE_URL = "http://www.github.com";
private CloseableHttpClient instance;
private CloseableHttpResponse response;
@Before
public final void before() {
instance = HttpClientBuilder.create().build();
}
@After
public final void after() throws IllegalStateException, IOException {
ResponseUtil.closeResponse(response);
}
// tests
// simple request - response
@Test
public final void whenExecutingBasicGetRequest_thenNoExceptions() throws ClientProtocolException, IOException {
response = instance.execute(new HttpGet(SAMPLE_URL));
public final void whenExecutingBasicGetRequest_thenNoExceptions() throws IOException {
final HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
}
}
@Test
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws ClientProtocolException, IOException {
response = instance.execute(new HttpGet(SAMPLE_URL));
final int statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException {
final HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(HttpStatus.SC_OK));
}
}
@Test
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectMimeType() throws ClientProtocolException, IOException {
response = instance.execute(new HttpGet(SAMPLE_URL));
final String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
@Test
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectMimeType() throws IOException {
final HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
final String contentMimeType = ContentType.parse(response.getEntity().getContentType()).getMimeType();
assertThat(contentMimeType, equalTo(ContentType.TEXT_HTML.getMimeType()));
}
}
@Test
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectBody() throws ClientProtocolException, IOException {
response = instance.execute(new HttpGet(SAMPLE_URL));
final String bodyAsString = EntityUtils.toString(response.getEntity());
public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectBody() throws IOException, ParseException {
final HttpGet request = new HttpGet(SAMPLE_URL);
try (CloseableHttpClient client = HttpClientBuilder.create().build();
assertThat(bodyAsString, notNullValue());
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response, notNullValue());
}
}
}

View File

@ -1,118 +1,119 @@
package com.baeldung.httpclient.sec;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpContext;
import com.baeldung.httpclient.ResponseUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.baeldung.handler.CustomHttpClientResponseHandler;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/*
* NOTE : Need module httpclient-simple to be running
*/
public class HttpClientAuthLiveTest {
class HttpClientAuthLiveTest {
private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8082/httpclient-simple/api/foos/1";
private static final String DEFAULT_USER = "user1";
private static final String DEFAULT_PASS = "user1Pass";
private CloseableHttpClient client;
private CloseableHttpResponse response;
@Before
public final void before() {
client = HttpClientBuilder.create().build();
}
@After
public final void after() throws IllegalStateException, IOException {
ResponseUtil.closeResponse(response);
}
// tests
private final char[] DEFAULT_PASS_ARRAY = DEFAULT_PASS.toCharArray() ;
@Test
public final void whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider()).build();
final void whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
try (CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(provider())
.build();
response = client.execute(new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION));
final int statusCode = response.getStatusLine().getStatusCode();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
final int statusCode = response.getCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}
@Test
public final void givenAuthenticationIsPreemptive_whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
client = HttpClientBuilder.create().build();
response = client.execute(new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION), context());
final int statusCode = response.getStatusLine().getStatusCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}
@Test
public final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess() throws IOException {
client = HttpClientBuilder.create().build();
final void givenAuthenticationIsPreemptive_whenExecutingBasicGetRequestWithBasicAuthenticationEnabled_thenSuccess() throws IOException {
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
try (CloseableHttpClient client = HttpClientBuilder.create()
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, context(), new CustomHttpClientResponseHandler())) {
final int statusCode = response.getCode();
assertThat(statusCode, equalTo(200));
}
}
@Test
final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess() throws IOException {
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
request.setHeader(HttpHeaders.AUTHORIZATION, authorizationHeader(DEFAULT_USER, DEFAULT_PASS));
response = client.execute(request);
try (CloseableHttpClient client = HttpClientBuilder.create()
.build();
final int statusCode = response.getStatusLine().getStatusCode();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, context(), new CustomHttpClientResponseHandler())) {
final int statusCode = response.getCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}
}
@Test
public final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess2() throws IOException {
final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess2() throws IOException {
final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION);
final String auth = DEFAULT_USER + ":" + DEFAULT_PASS;
final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
final String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
client = HttpClientBuilder.create().build();
response = client.execute(request);
try (CloseableHttpClient client = HttpClientBuilder.create()
.build();
final int statusCode = response.getStatusLine().getStatusCode();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
final int statusCode = response.getCode();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
}
}
// UTILS
private CredentialsProvider provider() {
final CredentialsProvider provider = new BasicCredentialsProvider();
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS);
provider.setCredentials(AuthScope.ANY, credentials);
final HttpHost targetHost = new HttpHost("http", "localhost", 8082);
final BasicCredentialsProvider provider = new BasicCredentialsProvider();
AuthScope authScope = new AuthScope(targetHost);
provider.setCredentials(authScope, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS_ARRAY));
return provider;
}
private HttpContext context() {
final HttpHost targetHost = new HttpHost("localhost", 8082, "http");
final CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS));
final HttpHost targetHost = new HttpHost("http", "localhost", 8082);
final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
AuthScope authScope = new AuthScope(targetHost);
credsProvider.setCredentials(authScope, new UsernamePasswordCredentials(DEFAULT_USER, DEFAULT_PASS_ARRAY));
// Create AuthCache instance
final AuthCache authCache = new BasicAuthCache();

View File

@ -26,24 +26,10 @@ class HttpClientCookieLiveTest {
final void whenSettingCookiesOnARequest_thenCorrect() throws IOException {
final HttpGet request = new HttpGet("http://www.github.com");
request.setHeader("Cookie", "JSESSIONID=1234");
try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler());) {
assertThat(response.getCode(), equalTo(200));
}
}
@Test
final void givenUsingDeprecatedApi_whenSettingCookiesOnTheHttpClient_thenCorrect() throws IOException {
final BasicCookieStore cookieStore = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setAttribute("domain", "true");
cookie.setPath("/");
cookieStore.addCookie(cookie);
final HttpGet request = new HttpGet("https://www.github.com");
try (CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.build(); CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler())) {
try (CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
}
@ -58,9 +44,12 @@ class HttpClientCookieLiveTest {
cookieStore.addCookie(cookie);
final HttpGet request = new HttpGet("http://www.github.com");
try (CloseableHttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, new CustomHttpClientResponseHandler())) {
try (CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
@ -79,7 +68,9 @@ class HttpClientCookieLiveTest {
// localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); // before 4.3
try (CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = (CloseableHttpResponse) client.execute(request, localContext, new CustomHttpClientResponseHandler())) {
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, localContext, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
}

View File

@ -25,6 +25,27 @@
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -38,7 +59,9 @@
</build>
<properties>
<h2.version>2.1.214</h2.version>
<rest-assured.version>3.1.1</rest-assured.version>
<spring-boot.version>2.5.0</spring-boot.version>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung.jackson.jsonignorevstransient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.jackson.jsonignorevstransient;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
class Person implements Serializable {
@JsonIgnore
private final Long id;
private final String firstName;
private final String lastName;
public Person(Long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

View File

@ -0,0 +1,64 @@
package com.baeldung.jackson.jsonignorevstransient;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.io.Serializable;
@Entity
@Table(name = "Users")
class User implements Serializable {
@Id
private Long id;
private String username;
private String password;
@Transient
private String repeatedPassword;
public User() {
}
public User(Long id, String username, String password, String repeatedPassword) {
this.id = id;
this.username = username;
this.password = password;
this.repeatedPassword = repeatedPassword;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRepeatedPassword() {
return repeatedPassword;
}
public void setRepeatedPassword(String repeatedPassword) {
this.repeatedPassword = repeatedPassword;
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.jackson.jsonignorevstransient;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

View File

@ -0,0 +1,23 @@
package com.baeldung.jackson.jsonignorevstransient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
class PersonUnitTest {
@Test
void givenPerson_whenSerializing_thenIdFieldIgnored() throws JsonProcessingException {
Person person = new Person(1L, "My First Name", "My Last Name");
String result = new ObjectMapper().writeValueAsString(person);
assertThat(result, containsString("firstName"));
assertThat(result, containsString("lastName"));
assertThat(result, not(containsString("id")));
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.jackson.jsonignorevstransient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@SpringBootTest
class UserUnitTest {
@Autowired
UserRepository userRepository;
@Test
void givenUser_whenSave_thenSkipTransientFields() {
User user = new User(1L, "user", "newPassword123", "newPassword123");
User savedUser = userRepository.save(user);
assertNotNull(savedUser);
assertNotNull(savedUser.getPassword());
assertNull(savedUser.getRepeatedPassword());
}
@Test
void givenUser_whenSerializing_thenTransientFieldNotIgnored() throws JsonProcessingException {
User user = new User(1L, "user", "newPassword123", "newPassword123");
String result = new ObjectMapper().writeValueAsString(user);
assertThat(result, containsString("user"));
assertThat(result, containsString("repeatedPassword"));
}
}

View File

@ -0,0 +1,5 @@
hibernate.hbm2ddl.auto=create-drop
spring.datasource.jdbcUrl=jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

View File

@ -1,2 +1,4 @@
## Relevant Articles
- [Trigger Another Job from a Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-trigger-new-job)
- [Fixing the “No Such DSL method” Error in Jenkins Pipeline](https://www.baeldung.com/ops/jenkins-pipeline-no-such-dsl-method-error)
- [Jenkins Pipeline Change to Another Folder](https://www.baeldung.com/ops/jenkins-pipeline-change-to-another-folder)

View File

@ -0,0 +1,15 @@
pipeline {
agent any
stages {
stage('Infinite Loop') {
steps {
script {
while (true) {
println 'This is an infinite loop!'
Thread.sleep(10000)
}
}
}
}
}
}

View File

@ -0,0 +1,3 @@
Jenkins.instance.getItemByFullName("sampleZombieJob")
.getBuildByNumber(17)
.finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"));

View File

@ -0,0 +1,6 @@
Thread.getAllStackTraces().keySet().each() {
if (it.name.contains('sampleZombieJob')) {
println "Stopping $it.name"
it.interrupt()
}
}

View File

@ -0,0 +1,6 @@
Thread.getAllStackTraces().keySet().each() {
if (it.name.contains('sampleZombieJob')) {
println "Stopping $it.name"
it.stop()
}
}

View File

@ -1,11 +1,15 @@
package com.baeldung.jsonvalidation;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
public class JacksonValidator {
final ObjectMapper mapper = new ObjectMapper();
final ObjectMapper mapper = JsonMapper.builder()
.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
.build();
public boolean isValid(String json) {
try {

View File

@ -2,3 +2,4 @@
### Relevant Articles:
- [How to Parse an INI File in Java](https://www.baeldung.com/java-parse-ini-file)
- [Using Watermarks with iText in Java](https://www.baeldung.com/java-watermarks-with-itext)

View File

@ -76,7 +76,7 @@
</build>
<properties>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
<springframework.version>4.3.4.RELEASE</springframework.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

View File

@ -19,6 +19,7 @@
<module>microprofile</module>
<module>msf4j</module>
<module>open-liberty</module>
<module>rest-express</module>
</modules>
</project>

View File

@ -0,0 +1,5 @@
## RestExpress
This module contains articles about RestExpress.
### Relevant articles

View File

@ -0,0 +1,153 @@
<?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">
<parent>
<artifactId>microservices-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>rest-express</name>
<!--
To run the project: mvn clean package exec:java
* mongod must be running.
To create a project deployable assembly (zip file):
mvn clean package
mvn assembly:single
-->
<description>A Basic, MongoDB-backed Service Suite</description>
<url>https://github.com/RestExpress/RestExpress-Scaffold</url>
<version>1.0.0-SNAPSHOT</version>
<artifactId>rest-express</artifactId>
<packaging>jar</packaging>
<properties>
<RestExpress.plugin.version>0.3.3</RestExpress.plugin.version>
<metrics-graphite.version>3.1.2</metrics-graphite.version>
<HyperExpressPlugin.version>2.6</HyperExpressPlugin.version>
<RestExpress.version>0.11.3</RestExpress.version>
<Syntaxe.version>1.0</Syntaxe.version>
<repoexpress-mongodb.version>0.4.8</repoexpress-mongodb.version>
<junit4.version>4.11</junit4.version>
</properties>
<dependencies>
<dependency>
<groupId>com.strategicgains</groupId>
<artifactId>RestExpress</artifactId>
<version>${RestExpress.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains</groupId>
<artifactId>Syntaxe</artifactId>
<version>${Syntaxe.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains.repoexpress</groupId>
<artifactId>repoexpress-mongodb</artifactId>
<version>${repoexpress-mongodb.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains.plugin-express</groupId>
<artifactId>CacheControlPlugin</artifactId>
<version>${RestExpress.plugin.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains</groupId>
<artifactId>HyperExpressPlugin</artifactId>
<version>${HyperExpressPlugin.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains.plugin-express</groupId>
<artifactId>MetricsPlugin</artifactId>
<version>${RestExpress.plugin.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains.plugin-express</groupId>
<artifactId>SwaggerPlugin</artifactId>
<version>${RestExpress.plugin.version}</version>
</dependency>
<dependency>
<groupId>com.strategicgains.plugin-express</groupId>
<artifactId>CORSPlugin</artifactId>
<version>${RestExpress.plugin.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-graphite</artifactId>
<version>${metrics-graphite.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit4.version}</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.baeldung.restexpress.Main</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.baeldung.restexpress.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,75 @@
package com.baeldung.restexpress;
import com.baeldung.restexpress.objectid.SampleOidEntityController;
import com.baeldung.restexpress.objectid.SampleOidEntityRepository;
import com.baeldung.restexpress.objectid.SampleOidEntityService;
import com.baeldung.restexpress.uuid.SampleUuidEntityController;
import com.baeldung.restexpress.uuid.SampleUuidEntityRepository;
import com.baeldung.restexpress.uuid.SampleUuidEntityService;
import com.strategicgains.repoexpress.mongodb.MongoConfig;
import com.strategicgains.restexpress.plugin.metrics.MetricsConfig;
import org.restexpress.RestExpress;
import org.restexpress.util.Environment;
import java.util.Properties;
public class Configuration
extends Environment {
private static final String DEFAULT_EXECUTOR_THREAD_POOL_SIZE = "20";
private static final String PORT_PROPERTY = "port";
private static final String BASE_URL_PROPERTY = "base.url";
private static final String EXECUTOR_THREAD_POOL_SIZE = "executor.threadPool.size";
private int port;
private String baseUrl;
private int executorThreadPoolSize;
private MetricsConfig metricsSettings;
private SampleUuidEntityController sampleUuidController;
private SampleOidEntityController sampleOidController;
@Override
protected void fillValues(Properties p) {
this.port = Integer.parseInt(p.getProperty(PORT_PROPERTY, String.valueOf(RestExpress.DEFAULT_PORT)));
this.baseUrl = p.getProperty(BASE_URL_PROPERTY, "http://localhost:" + String.valueOf(port));
this.executorThreadPoolSize = Integer.parseInt(p.getProperty(EXECUTOR_THREAD_POOL_SIZE, DEFAULT_EXECUTOR_THREAD_POOL_SIZE));
this.metricsSettings = new MetricsConfig(p);
MongoConfig mongo = new MongoConfig(p);
initialize(mongo);
}
private void initialize(MongoConfig mongo) {
SampleUuidEntityRepository samplesUuidRepository = new SampleUuidEntityRepository(mongo.getClient(), mongo.getDbName());
SampleUuidEntityService sampleUuidService = new SampleUuidEntityService(samplesUuidRepository);
sampleUuidController = new SampleUuidEntityController(sampleUuidService);
SampleOidEntityRepository samplesOidRepository = new SampleOidEntityRepository(mongo.getClient(), mongo.getDbName());
SampleOidEntityService sampleOidService = new SampleOidEntityService(samplesOidRepository);
sampleOidController = new SampleOidEntityController(sampleOidService);
}
public int getPort() {
return port;
}
public String getBaseUrl() {
return baseUrl;
}
public int getExecutorThreadPoolSize() {
return executorThreadPoolSize;
}
public MetricsConfig getMetricsConfig() {
return metricsSettings;
}
public SampleUuidEntityController getSampleUuidEntityController() {
return sampleUuidController;
}
public SampleOidEntityController getSampleOidEntityController() {
return sampleOidController;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.restexpress;
public class Constants {
/**
* These define the URL parmaeters used in the route definition strings (e.g. '{userId}').
*/
public class Url {
//TODO: Your URL parameter names here...
public static final String SAMPLE_ID = "uuid";
}
/**
* These define the route names used in naming each route definitions. These names are used
* to retrieve URL patterns within the controllers by name to create links in responses.
*/
public class Routes {
//TODO: Your Route names here...
public static final String SINGLE_UUID_SAMPLE = "sample.single.route.uuid";
public static final String SAMPLE_UUID_COLLECTION = "sample.collection.route.uuid";
public static final String SINGLE_OID_SAMPLE = "sample.single.route.oid";
public static final String SAMPLE_OID_COLLECTION = "sample.collection.route.oid";
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.restexpress;
import com.strategicgains.repoexpress.domain.Timestamped;
import com.strategicgains.util.date.DateAdapter;
import com.strategicgains.util.date.HttpHeaderTimestampAdapter;
import org.restexpress.Request;
import org.restexpress.Response;
import org.restexpress.pipeline.Postprocessor;
import static io.netty.handler.codec.http.HttpHeaders.Names.LAST_MODIFIED;
/**
* Assigns the Last-Modified HTTP header on the response for GET responses, if applicable.
*
* @author toddf
* @since May 15, 2012
*/
public class LastModifiedHeaderPostprocessor
implements Postprocessor {
DateAdapter fmt = new HttpHeaderTimestampAdapter();
@Override
public void process(Request request, Response response) {
if (!request.isMethodGet()) return;
if (!response.hasBody()) return;
Object body = response.getBody();
if (!response.hasHeader(LAST_MODIFIED) && body.getClass().isAssignableFrom(Timestamped.class)) {
response.addHeader(LAST_MODIFIED, fmt.format(((Timestamped) body).getUpdatedAt()));
}
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.restexpress;
import org.restexpress.util.Environment;
public class Main {
public static void main(String[] args) throws Exception {
Configuration config = Environment.load(args, Configuration.class);
Server server = new Server(config);
server.start().awaitShutdown();
}
}

View File

@ -0,0 +1,55 @@
package com.baeldung.restexpress;
import com.baeldung.restexpress.objectid.SampleOidEntity;
import com.baeldung.restexpress.uuid.SampleUuidEntity;
import com.strategicgains.hyperexpress.HyperExpress;
import com.strategicgains.hyperexpress.RelTypes;
import org.restexpress.RestExpress;
import org.restexpress.common.exception.ConfigurationException;
import java.util.Map;
public abstract class Relationships {
private static Map<String, String> ROUTES;
public static void define(RestExpress server) {
ROUTES = server.getRouteUrlsByName();
HyperExpress.relationships()
.forCollectionOf(SampleUuidEntity.class)
.rel(RelTypes.SELF, href(Constants.Routes.SAMPLE_UUID_COLLECTION))
.withQuery("limit={limit}")
.withQuery("offset={offset}")
.rel(RelTypes.NEXT, href(Constants.Routes.SAMPLE_UUID_COLLECTION) + "?offset={nextOffset}")
.withQuery("limit={limit}")
.optional()
.rel(RelTypes.PREV, href(Constants.Routes.SAMPLE_UUID_COLLECTION) + "?offset={prevOffset}")
.withQuery("limit={limit}")
.optional()
.forClass(SampleUuidEntity.class)
.rel(RelTypes.SELF, href(Constants.Routes.SINGLE_UUID_SAMPLE))
.rel(RelTypes.UP, href(Constants.Routes.SAMPLE_UUID_COLLECTION))
.forCollectionOf(SampleOidEntity.class)
.rel(RelTypes.SELF, href(Constants.Routes.SAMPLE_OID_COLLECTION))
.withQuery("limit={limit}")
.withQuery("offset={offset}")
.rel(RelTypes.NEXT, href(Constants.Routes.SAMPLE_OID_COLLECTION) + "?offset={nextOffset}")
.withQuery("limit={limit}")
.optional()
.rel(RelTypes.PREV, href(Constants.Routes.SAMPLE_OID_COLLECTION) + "?offset={prevOffset}")
.withQuery("limit={limit}")
.optional()
.forClass(SampleOidEntity.class)
.rel(RelTypes.SELF, href(Constants.Routes.SINGLE_OID_SAMPLE))
.rel(RelTypes.UP, href(Constants.Routes.SAMPLE_OID_COLLECTION));
}
private static String href(String name) {
String href = ROUTES.get(name);
if (href == null) throw new ConfigurationException("Route name not found: " + name);
return href;
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.restexpress;
import io.netty.handler.codec.http.HttpMethod;
import org.restexpress.RestExpress;
public abstract class Routes {
public static void define(Configuration config, RestExpress server) {
// TODO: Your routes here...
server.uri("/samples/uuid/{uuid}.{format}", config.getSampleUuidEntityController())
.method(HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE)
.name(Constants.Routes.SINGLE_UUID_SAMPLE);
server.uri("/samples/uuid.{format}", config.getSampleUuidEntityController())
.action("readAll", HttpMethod.GET)
.method(HttpMethod.POST)
.name(Constants.Routes.SAMPLE_UUID_COLLECTION);
server.uri("/samples/oid/{uuid}.{format}", config.getSampleOidEntityController())
.method(HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE)
.name(Constants.Routes.SINGLE_OID_SAMPLE);
server.uri("/samples/oid.{format}", config.getSampleOidEntityController())
.action("readAll", HttpMethod.GET)
.method(HttpMethod.POST)
.name(Constants.Routes.SAMPLE_OID_COLLECTION);
// or REGEX matching routes...
// server.regex("/some.regex", config.getRouteController());
}
}

View File

@ -0,0 +1,129 @@
package com.baeldung.restexpress;
import com.baeldung.restexpress.serialization.SerializationProvider;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter;
import com.strategicgains.repoexpress.adapter.Identifiers;
import com.strategicgains.repoexpress.exception.DuplicateItemException;
import com.strategicgains.repoexpress.exception.InvalidObjectIdException;
import com.strategicgains.repoexpress.exception.ItemNotFoundException;
import com.strategicgains.restexpress.plugin.cache.CacheControlPlugin;
import com.strategicgains.restexpress.plugin.cors.CorsHeaderPlugin;
import com.strategicgains.restexpress.plugin.metrics.MetricsConfig;
import com.strategicgains.restexpress.plugin.metrics.MetricsPlugin;
import com.strategicgains.restexpress.plugin.swagger.SwaggerPlugin;
import com.strategicgains.syntaxe.ValidationException;
import org.restexpress.Flags;
import org.restexpress.RestExpress;
import org.restexpress.exception.BadRequestException;
import org.restexpress.exception.ConflictException;
import org.restexpress.exception.NotFoundException;
import org.restexpress.pipeline.SimpleConsoleLogMessageObserver;
import org.restexpress.plugin.hyperexpress.HyperExpressPlugin;
import org.restexpress.plugin.hyperexpress.Linkable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.restexpress.Flags.Auth.PUBLIC_ROUTE;
public class Server {
private static final String SERVICE_NAME = "TODO: Enter service name";
private static final Logger LOG = LoggerFactory.getLogger(SERVICE_NAME);
private RestExpress server;
private Configuration config;
private boolean isStarted = false;
public Server(Configuration config) {
this.config = config;
RestExpress.setDefaultSerializationProvider(new SerializationProvider());
Identifiers.UUID.useShortUUID(true);
this.server = new RestExpress()
.setName(SERVICE_NAME)
.setBaseUrl(config.getBaseUrl())
.setExecutorThreadCount(config.getExecutorThreadPoolSize())
.addMessageObserver(new SimpleConsoleLogMessageObserver());
Routes.define(config, server);
Relationships.define(server);
configurePlugins(config, server);
mapExceptions(server);
}
public Server start() {
if (!isStarted) {
server.bind(config.getPort());
isStarted = true;
}
return this;
}
public void awaitShutdown() {
if (isStarted) server.awaitShutdown();
}
public void shutdown() {
if (isStarted) server.shutdown();
}
private void configurePlugins(Configuration config, RestExpress server) {
configureMetrics(config, server);
new SwaggerPlugin()
.flag(Flags.Auth.PUBLIC_ROUTE)
.register(server);
new CacheControlPlugin()
.register(server);
new HyperExpressPlugin(Linkable.class)
.register(server);
new CorsHeaderPlugin("*")
.flag(PUBLIC_ROUTE)
.allowHeaders(CONTENT_TYPE, ACCEPT, AUTHORIZATION, REFERER, LOCATION)
.exposeHeaders(LOCATION)
.register(server);
}
private void configureMetrics(Configuration config, RestExpress server) {
MetricsConfig mc = config.getMetricsConfig();
if (mc.isEnabled()) {
MetricRegistry registry = new MetricRegistry();
new MetricsPlugin(registry)
.register(server);
if (mc.isGraphiteEnabled()) {
final Graphite graphite = new Graphite(new InetSocketAddress(mc.getGraphiteHost(), mc.getGraphitePort()));
final GraphiteReporter reporter = GraphiteReporter.forRegistry(registry)
.prefixedWith(mc.getPrefix())
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.filter(MetricFilter.ALL)
.build(graphite);
reporter.start(mc.getPublishSeconds(), TimeUnit.SECONDS);
} else {
LOG.warn("*** Graphite Metrics Publishing is Disabled ***");
}
} else {
LOG.warn("*** Metrics Generation is Disabled ***");
}
}
private void mapExceptions(RestExpress server) {
server
.mapException(ItemNotFoundException.class, NotFoundException.class)
.mapException(DuplicateItemException.class, ConflictException.class)
.mapException(ValidationException.class, BadRequestException.class)
.mapException(InvalidObjectIdException.class, BadRequestException.class);
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.restexpress.objectid;
import com.baeldung.restexpress.Constants;
import com.strategicgains.hyperexpress.annotation.BindToken;
import com.strategicgains.hyperexpress.annotation.TokenBindings;
import com.strategicgains.repoexpress.mongodb.AbstractMongodbEntity;
import org.restexpress.plugin.hyperexpress.Linkable;
/**
* This is a sample entity identified by a MongoDB ObjectID (instead of a UUID).
* It also contains createdAt and updatedAt properties that are automatically maintained
* by the persistence layer (SampleOidEntityRepository).
*/
@TokenBindings({
@BindToken(value = Constants.Url.SAMPLE_ID, field = "id")
})
public class SampleOidEntity
extends AbstractMongodbEntity
implements Linkable {
private String name;
public SampleOidEntity() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,80 @@
package com.baeldung.restexpress.objectid;
import com.baeldung.restexpress.Constants;
import com.strategicgains.hyperexpress.builder.DefaultTokenResolver;
import com.strategicgains.hyperexpress.builder.DefaultUrlBuilder;
import com.strategicgains.hyperexpress.builder.UrlBuilder;
import com.strategicgains.repoexpress.mongodb.Identifiers;
import io.netty.handler.codec.http.HttpMethod;
import org.restexpress.Request;
import org.restexpress.Response;
import org.restexpress.common.query.QueryFilter;
import org.restexpress.common.query.QueryOrder;
import org.restexpress.common.query.QueryRange;
import org.restexpress.query.QueryFilters;
import org.restexpress.query.QueryOrders;
import org.restexpress.query.QueryRanges;
import java.util.List;
/**
* This is the 'controller' layer, where HTTP details are converted to domain concepts and passed to the service layer.
* Then service layer response information is enhanced with HTTP details, if applicable, for the response.
* <p/>
* This controller demonstrates how to process an entity that is identified by a MongoDB ObjectId.
*/
public class SampleOidEntityController {
private static final UrlBuilder LOCATION_BUILDER = new DefaultUrlBuilder();
private SampleOidEntityService service;
public SampleOidEntityController(SampleOidEntityService sampleService) {
super();
this.service = sampleService;
}
public SampleOidEntity create(Request request, Response response) {
SampleOidEntity entity = request.getBodyAs(SampleOidEntity.class, "Resource details not provided");
SampleOidEntity saved = service.create(entity);
// Construct the response for create...
response.setResponseCreated();
// Include the Location header...
String locationPattern = request.getNamedUrl(HttpMethod.GET, Constants.Routes.SINGLE_OID_SAMPLE);
response.addLocationHeader(LOCATION_BUILDER.build(locationPattern, new DefaultTokenResolver()));
// Return the newly-created resource...
return saved;
}
public SampleOidEntity read(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
SampleOidEntity entity = service.read(Identifiers.MONGOID.parse(id));
return entity;
}
public List<SampleOidEntity> readAll(Request request, Response response) {
QueryFilter filter = QueryFilters.parseFrom(request);
QueryOrder order = QueryOrders.parseFrom(request);
QueryRange range = QueryRanges.parseFrom(request, 20);
List<SampleOidEntity> entities = service.readAll(filter, range, order);
long count = service.count(filter);
response.setCollectionResponse(range, entities.size(), count);
return entities;
}
public void update(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
SampleOidEntity entity = request.getBodyAs(SampleOidEntity.class, "Resource details not provided");
entity.setId(Identifiers.MONGOID.parse(id));
service.update(entity);
response.setResponseNoContent();
}
public void delete(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
service.delete(Identifiers.MONGOID.parse(id));
response.setResponseNoContent();
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.restexpress.objectid;
import com.mongodb.MongoClient;
import com.strategicgains.repoexpress.mongodb.MongodbEntityRepository;
public class SampleOidEntityRepository
extends MongodbEntityRepository<SampleOidEntity> {
@SuppressWarnings("unchecked")
public SampleOidEntityRepository(MongoClient mongo, String dbName) {
super(mongo, dbName, SampleOidEntity.class);
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.restexpress.objectid;
import com.strategicgains.repoexpress.domain.Identifier;
import com.strategicgains.syntaxe.ValidationEngine;
import org.restexpress.common.query.QueryFilter;
import org.restexpress.common.query.QueryOrder;
import org.restexpress.common.query.QueryRange;
import java.util.List;
/**
* This is the 'service' or 'business logic' layer, where business logic, syntactic and semantic
* domain validation occurs, along with calls to the persistence layer.
*/
public class SampleOidEntityService {
private SampleOidEntityRepository samples;
public SampleOidEntityService(SampleOidEntityRepository samplesRepository) {
super();
this.samples = samplesRepository;
}
public SampleOidEntity create(SampleOidEntity entity) {
ValidationEngine.validateAndThrow(entity);
return samples.create(entity);
}
public SampleOidEntity read(Identifier id) {
return samples.read(id);
}
public void update(SampleOidEntity entity) {
ValidationEngine.validateAndThrow(entity);
samples.update(entity);
}
public void delete(Identifier id) {
samples.delete(id);
}
public List<SampleOidEntity> readAll(QueryFilter filter, QueryRange range, QueryOrder order) {
return samples.readAll(filter, range, order);
}
public long count(QueryFilter filter) {
return samples.count(filter);
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.restexpress.serialization;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.strategicgains.hyperexpress.domain.hal.HalResource;
import com.strategicgains.hyperexpress.serialization.jackson.HalResourceDeserializer;
import com.strategicgains.hyperexpress.serialization.jackson.HalResourceSerializer;
import org.bson.types.ObjectId;
import org.restexpress.ContentType;
import org.restexpress.serialization.json.JacksonJsonProcessor;
import java.util.UUID;
public class JsonSerializationProcessor
extends JacksonJsonProcessor {
public JsonSerializationProcessor() {
super();
addSupportedMediaTypes(ContentType.HAL_JSON);
}
@Override
protected void initializeModule(SimpleModule module) {
super.initializeModule(module);
// For UUID as entity identifiers...
module.addDeserializer(UUID.class, new UuidDeserializer());
module.addSerializer(UUID.class, new UuidSerializer());
// For MongoDB ObjectId as entity identifiers...
module.addDeserializer(ObjectId.class, new ObjectIdDeserializer());
module.addSerializer(ObjectId.class, new ObjectIdSerializer());
// Support HalResource (de)serialization.
module.addDeserializer(HalResource.class, new HalResourceDeserializer());
module.addSerializer(HalResource.class, new HalResourceSerializer());
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.restexpress.serialization;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.strategicgains.repoexpress.mongodb.Identifiers;
import org.bson.types.ObjectId;
import java.io.IOException;
public class ObjectIdDeserializer
extends JsonDeserializer<ObjectId> {
@Override
public ObjectId deserialize(JsonParser json, DeserializationContext context)
throws IOException, JsonProcessingException {
return (ObjectId) Identifiers.MONGOID.parse(json.getText()).primaryKey();
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.restexpress.serialization;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.bson.types.ObjectId;
import java.io.IOException;
public class ObjectIdSerializer
extends JsonSerializer<ObjectId> {
@Override
public void serialize(ObjectId objectId, JsonGenerator json, SerializerProvider provider)
throws IOException, JsonProcessingException {
json.writeString(objectId.toString());
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.restexpress.serialization;
import org.restexpress.response.ErrorResponseWrapper;
import org.restexpress.response.ResponseWrapper;
import org.restexpress.serialization.AbstractSerializationProvider;
import org.restexpress.serialization.SerializationProcessor;
public class SerializationProvider
extends AbstractSerializationProvider {
// SECTION: CONSTANTS
private static final SerializationProcessor JSON_SERIALIZER = new JsonSerializationProcessor();
private static final SerializationProcessor XML_SERIALIZER = new XmlSerializationProcessor();
private static final ResponseWrapper RESPONSE_WRAPPER = new ErrorResponseWrapper();
public SerializationProvider() {
super();
add(JSON_SERIALIZER, RESPONSE_WRAPPER, true);
add(XML_SERIALIZER, RESPONSE_WRAPPER);
}
public static SerializationProcessor json() {
return JSON_SERIALIZER;
}
public static SerializationProcessor xml() {
return XML_SERIALIZER;
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.restexpress.serialization;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.strategicgains.repoexpress.util.UuidConverter;
import java.io.IOException;
import java.util.UUID;
public class UuidDeserializer
extends JsonDeserializer<UUID> {
@Override
public UUID deserialize(JsonParser json, DeserializationContext context)
throws IOException, JsonProcessingException {
return UuidConverter.parse(json.getText());
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.restexpress.serialization;
import com.strategicgains.hyperexpress.annotation.TokenFormatter;
import com.strategicgains.repoexpress.util.UuidConverter;
import java.util.UUID;
public class UuidFormatter
implements TokenFormatter {
@Override
public String format(Object field) {
return UuidConverter.format((UUID) field);
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.restexpress.serialization;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.strategicgains.repoexpress.util.UuidConverter;
import java.io.IOException;
import java.util.UUID;
public class UuidSerializer
extends JsonSerializer<UUID> {
@Override
public void serialize(UUID objectId, JsonGenerator json, SerializerProvider provider)
throws IOException, JsonProcessingException {
json.writeString(UuidConverter.format(objectId));
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.restexpress.serialization;
import com.baeldung.restexpress.uuid.SampleUuidEntity;
import org.restexpress.serialization.xml.XstreamXmlProcessor;
public class XmlSerializationProcessor
extends XstreamXmlProcessor {
public XmlSerializationProcessor() {
super();
alias("sample", SampleUuidEntity.class);
// alias("element_name", Element.class);
// alias("element_name", Element.class);
// alias("element_name", Element.class);
// alias("element_name", Element.class);
registerConverter(new XstreamUuidConverter());
registerConverter(new XstreamOidConverter());
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.restexpress.serialization;
import com.strategicgains.repoexpress.mongodb.Identifiers;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import org.bson.types.ObjectId;
/**
* @author toddf
* @since Feb 16, 2011
*/
public class XstreamOidConverter
implements SingleValueConverter {
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class aClass) {
return ObjectId.class.isAssignableFrom(aClass);
}
@Override
public Object fromString(String value) {
return (ObjectId) Identifiers.MONGOID.parse(value).primaryKey();
}
@Override
public String toString(Object objectId) {
return ((ObjectId) objectId).toString();
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.restexpress.serialization;
import com.strategicgains.repoexpress.util.UuidConverter;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import java.util.UUID;
/**
* @author toddf
* @since Feb 16, 2011
*/
public class XstreamUuidConverter
implements SingleValueConverter {
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class aClass) {
return UUID.class.isAssignableFrom(aClass);
}
@Override
public Object fromString(String value) {
return UuidConverter.parse(value);
}
@Override
public String toString(Object objectId) {
return UuidConverter.format((UUID) objectId);
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.restexpress.uuid;
import com.baeldung.restexpress.Constants;
import com.baeldung.restexpress.serialization.UuidFormatter;
import com.strategicgains.hyperexpress.annotation.BindToken;
import com.strategicgains.hyperexpress.annotation.TokenBindings;
import com.strategicgains.repoexpress.mongodb.AbstractUuidMongodbEntity;
import org.restexpress.plugin.hyperexpress.Linkable;
/**
* This is a sample entity identified by a UUID (instead of a MongoDB ObjectID).
* It also contains createdAt and updatedAt properties that are automatically maintained
* by the persistence layer (SampleUuidEntityRepository).
*/
@TokenBindings({
@BindToken(value = Constants.Url.SAMPLE_ID, field = "id", formatter = UuidFormatter.class)
})
public class SampleUuidEntity
extends AbstractUuidMongodbEntity
implements Linkable {
public SampleUuidEntity() {
}
}

View File

@ -0,0 +1,79 @@
package com.baeldung.restexpress.uuid;
import com.baeldung.restexpress.Constants;
import com.strategicgains.hyperexpress.builder.DefaultTokenResolver;
import com.strategicgains.hyperexpress.builder.DefaultUrlBuilder;
import com.strategicgains.hyperexpress.builder.UrlBuilder;
import com.strategicgains.repoexpress.adapter.Identifiers;
import io.netty.handler.codec.http.HttpMethod;
import org.restexpress.Request;
import org.restexpress.Response;
import org.restexpress.common.query.QueryFilter;
import org.restexpress.common.query.QueryOrder;
import org.restexpress.common.query.QueryRange;
import org.restexpress.query.QueryFilters;
import org.restexpress.query.QueryOrders;
import org.restexpress.query.QueryRanges;
import java.util.List;
/**
* This is the 'controller' layer, where HTTP details are converted to domain concepts and passed to the service layer.
* Then service layer response information is enhanced with HTTP details, if applicable, for the response.
* <p/>
* This controller demonstrates how to process a MongoDB entity that is identified by a UUID.
*/
public class SampleUuidEntityController {
private static final UrlBuilder LOCATION_BUILDER = new DefaultUrlBuilder();
private SampleUuidEntityService service;
public SampleUuidEntityController(SampleUuidEntityService sampleService) {
super();
this.service = sampleService;
}
public SampleUuidEntity create(Request request, Response response) {
SampleUuidEntity entity = request.getBodyAs(SampleUuidEntity.class, "Resource details not provided");
SampleUuidEntity saved = service.create(entity);
// Construct the response for create...
response.setResponseCreated();
// Include the Location header...
String locationPattern = request.getNamedUrl(HttpMethod.GET, Constants.Routes.SINGLE_UUID_SAMPLE);
response.addLocationHeader(LOCATION_BUILDER.build(locationPattern, new DefaultTokenResolver()));
// Return the newly-created resource...
return saved;
}
public SampleUuidEntity read(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
SampleUuidEntity entity = service.read(Identifiers.UUID.parse(id));
return entity;
}
public List<SampleUuidEntity> readAll(Request request, Response response) {
QueryFilter filter = QueryFilters.parseFrom(request);
QueryOrder order = QueryOrders.parseFrom(request);
QueryRange range = QueryRanges.parseFrom(request, 20);
List<SampleUuidEntity> entities = service.readAll(filter, range, order);
long count = service.count(filter);
response.setCollectionResponse(range, entities.size(), count);
return entities;
}
public void update(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
SampleUuidEntity entity = request.getBodyAs(SampleUuidEntity.class, "Resource details not provided");
entity.setId(Identifiers.UUID.parse(id));
service.update(entity);
response.setResponseNoContent();
}
public void delete(Request request, Response response) {
String id = request.getHeader(Constants.Url.SAMPLE_ID, "No resource ID supplied");
service.delete(Identifiers.UUID.parse(id));
response.setResponseNoContent();
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.restexpress.uuid;
import com.mongodb.MongoClient;
import com.strategicgains.repoexpress.mongodb.MongodbUuidEntityRepository;
public class SampleUuidEntityRepository
extends MongodbUuidEntityRepository<SampleUuidEntity> {
@SuppressWarnings("unchecked")
public SampleUuidEntityRepository(MongoClient mongo, String dbName) {
super(mongo, dbName, SampleUuidEntity.class);
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.restexpress.uuid;
import com.strategicgains.repoexpress.domain.Identifier;
import com.strategicgains.syntaxe.ValidationEngine;
import org.restexpress.common.query.QueryFilter;
import org.restexpress.common.query.QueryOrder;
import org.restexpress.common.query.QueryRange;
import java.util.List;
/**
* This is the 'service' or 'business logic' layer, where business logic, syntactic and semantic
* domain validation occurs, along with calls to the persistence layer.
*/
public class SampleUuidEntityService {
private SampleUuidEntityRepository samples;
public SampleUuidEntityService(SampleUuidEntityRepository samplesRepository) {
super();
this.samples = samplesRepository;
}
public SampleUuidEntity create(SampleUuidEntity entity) {
ValidationEngine.validateAndThrow(entity);
return samples.create(entity);
}
public SampleUuidEntity read(Identifier id) {
return samples.read(id);
}
public void update(SampleUuidEntity entity) {
ValidationEngine.validateAndThrow(entity);
samples.update(entity);
}
public void delete(Identifier id) {
samples.delete(id);
}
public List<SampleUuidEntity> readAll(QueryFilter filter, QueryRange range, QueryOrder order) {
return samples.readAll(filter, range, order);
}
public long count(QueryFilter filter) {
return samples.count(filter);
}
}

View File

@ -0,0 +1,22 @@
# Default is 8081
port = 8081
# The size of the executor thread pool (that can handle blocking back-end processing).
executor.threadPool.size = 20
# A MongoDB URI/Connection string
# see: http://docs.mongodb.org/manual/reference/connection-string/
mongodb.uri = mongodb://localhost:27017/scaffolding_mongodb
# The base URL, used as a prefix for links returned in data
# default is http://localhost:<port>
#base.url = http://localhost:8081
#Configuration for the MetricsPlugin/Graphite
metrics.isEnabled = true
#metrics.machineName =
metrics.prefix = web1.example.com
metrics.graphite.isEnabled = false
metrics.graphite.host = graphite.example.com
metrics.graphite.port = 2003
metrics.graphite.publishSeconds = 60

Some files were not shown because too many files have changed in this diff Show More