Merge branch 'eugenp:master' into PR-6865

This commit is contained in:
parthiv39731 2023-08-25 00:35:54 +05:30 committed by GitHub
commit 5c67e16385
24 changed files with 565 additions and 110 deletions

View File

@ -0,0 +1,79 @@
package com.baeldung.s3;
import java.util.List;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
public class RenameObjectService {
private S3Client s3Client;
public RenameObjectService(S3Client s3Client) {
this.s3Client = s3Client;
}
public RenameObjectService() {
init();
}
public void init() {
this.s3Client = S3Client.builder()
.region(Region.US_EAST_1)
.credentialsProvider(ProfileCredentialsProvider.create("default"))
.build();
}
public void renameFile(String bucketName, String keyName, String destinationKeyName) {
CopyObjectRequest copyObjRequest = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(keyName)
.destinationBucket(destinationKeyName)
.destinationKey(bucketName)
.build();
s3Client.copyObject(copyObjRequest);
DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
s3Client.deleteObject(deleteRequest);
}
public void renameFolder(String bucketName, String sourceFolderKey, String destinationFolderKey) {
ListObjectsV2Request listRequest = ListObjectsV2Request.builder()
.bucket(bucketName)
.prefix(sourceFolderKey)
.build();
ListObjectsV2Response listResponse = s3Client.listObjectsV2(listRequest);
List<S3Object> objects = listResponse.contents();
for (S3Object s3Object : objects) {
String newKey = destinationFolderKey + s3Object.key()
.substring(sourceFolderKey.length());
// Copy object to destination folder
CopyObjectRequest copyRequest = CopyObjectRequest.builder()
.sourceBucket(bucketName)
.sourceKey(s3Object.key())
.destinationBucket(bucketName)
.destinationKey(newKey)
.build();
s3Client.copyObject(copyRequest);
// Delete object from source folder
DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(s3Object.key())
.build();
s3Client.deleteObject(deleteRequest);
}
}
}

View File

@ -20,6 +20,17 @@
<version>${junit-platform.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.1-jre</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,75 @@
package com.baeldung.cartesianproduct;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
public class CartesianProduct {
public List<List<Object>> getCartesianProductIterative(List<List<Object>> sets) {
List<List<Object>> result = new ArrayList<>();
if(sets == null || sets.isEmpty()) {
return result;
}
int totalSets = sets.size();
int totalCombinations = 1 << totalSets;
for(int i = 0; i < totalCombinations; i++) {
List<Object> combination = new ArrayList<>();
for(int j = 0; j < totalSets; j++) {
if (((i >> j) & 1) == 1) {
combination.add(sets.get(j).get(0));
} else {
combination.add(sets.get(j).get(1));
}
}
result.add(combination);
}
return result;
}
public List<List<Object>> getCartesianProductRecursive(List<List<Object>> sets) {
List<List<Object>> result = new ArrayList<>();
getCartesianProductRecursiveHelper(sets, 0, new ArrayList<>(), result);
return result;
}
private void getCartesianProductRecursiveHelper(List<List<Object>> sets, int index, List<Object> current, List<List<Object>> result) {
if(index == sets.size()) {
result.add(new ArrayList<>(current));
return;
}
List<Object> currentSet = sets.get(index);
for(Object element: currentSet) {
current.add(element);
getCartesianProductRecursiveHelper(sets, index+1, current, result);
current.remove(current.size() - 1);
}
}
public List<List<Object>> getCartesianProductUsingStreams(List<List<Object>> sets) {
return cartesianProduct(sets,0).collect(Collectors.toList());
}
public Stream<List<Object>> cartesianProduct(List<List<Object>> sets, int index) {
if(index == sets.size()) {
List<Object> emptyList = new ArrayList<>();
return Stream.of(emptyList);
}
List<Object> currentSet = sets.get(index);
return currentSet.stream().flatMap(element -> cartesianProduct(sets, index+1)
.map(list -> {
List<Object> newList = new ArrayList<>(list);
newList.add(0, element); return newList;
}));
}
public List<List<Object>> getCartesianProductUsingGuava(List<Set<Object>> sets) {
Set<List<Object>> cartesianProduct = Sets.cartesianProduct(sets);
List<List<Object>> cartesianList = new ArrayList<>(cartesianProduct);
return cartesianList;
}
}

View File

@ -0,0 +1,93 @@
package com.baeldung.cartesianproduct;
import static org.testng.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.testng.annotations.Test;
public class CartesianProductUnitTest {
private CartesianProduct cp = new CartesianProduct();
List<List<Object>> sets = Arrays.asList(
Arrays.asList(10, 20),
Arrays.asList("John", "Jack"),
Arrays.asList('I', 'J')
);
@Test
public void whenUsingStreams_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingStreams(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingRecursion_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductRecursive(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingIterativeApproach_thenCalculateCartesianProduct() {
List<List<Object>> expected = Arrays.asList(
Arrays.asList(20, "Jack", 'J'),
Arrays.asList(10, "Jack", 'J'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(20, "John", 'I'),
Arrays.asList(10, "John", 'I')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductIterative(sets);
assertEquals(expected, cartesianProduct);
}
@Test
public void whenUsingGuava_thenCalculateCartesianProduct() {
List<Set<Object>> sets = new ArrayList<>();
sets.add(new HashSet<>(Arrays.asList(10, 20)));
sets.add(new HashSet<>(Arrays.asList("John", "Jack")));
sets.add(new HashSet<>(Arrays.asList('I', 'J')));
List<List<Object>> expected = Arrays.asList(
Arrays.asList(20, "John", 'I'),
Arrays.asList(20, "John", 'J'),
Arrays.asList(20, "Jack", 'I'),
Arrays.asList(20, "Jack", 'J'),
Arrays.asList(10, "John", 'I'),
Arrays.asList(10, "John", 'J'),
Arrays.asList(10, "Jack", 'I'),
Arrays.asList(10, "Jack", 'J')
);
List<List<Object>> cartesianProduct = cp.getCartesianProductUsingGuava(sets);
assertEquals(expected, cartesianProduct);
}
}

View File

@ -7,31 +7,37 @@ import java.util.concurrent.Phaser;
class LongRunningAction implements Runnable {
private static Logger log = LoggerFactory.getLogger(LongRunningAction.class);
private String threadName;
private Phaser ph;
private static final Logger log = LoggerFactory.getLogger(LongRunningAction.class);
private final String threadName;
private final Phaser ph;
LongRunningAction(String threadName, Phaser ph) {
this.threadName = threadName;
this.ph = ph;
this.randomWait();
ph.register();
log.info("Thread {} registered during phase {}", threadName, ph.getPhase());
}
@Override
public void run() {
log.info("This is phase {}", ph.getPhase());
log.info("Thread {} before long running action", threadName);
log.info("Thread {} BEFORE long running action in phase {}", threadName, ph.getPhase());
ph.arriveAndAwaitAdvance();
randomWait();
log.info("Thread {} AFTER long running action in phase {}", threadName, ph.getPhase());
ph.arriveAndDeregister();
}
// Simulating real work
private void randomWait() {
try {
Thread.sleep(2000);
Thread.sleep((long) (Math.random() * 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("Thread {} action completed and waiting for others", threadName);
ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", threadName, ph.getPhase());
ph.arriveAndDeregister();
}
}

View File

@ -7,8 +7,6 @@ import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;
import static junit.framework.TestCase.assertEquals;
@ -16,38 +14,32 @@ import static junit.framework.TestCase.assertEquals;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PhaserUnitTest {
private static Logger log = LoggerFactory.getLogger(PhaserUnitTest.class);
private static final Logger log = LoggerFactory.getLogger(PhaserUnitTest.class);
@Test
public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() {
//given
ExecutorService executorService = Executors.newCachedThreadPool();
public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() throws InterruptedException {
Phaser ph = new Phaser(1);
assertEquals(0, ph.getPhase());
//when
executorService.submit(new LongRunningAction("thread-1", ph));
executorService.submit(new LongRunningAction("thread-2", ph));
executorService.submit(new LongRunningAction("thread-3", ph));
new Thread(new LongRunningAction("thread-1", ph)).start();
new Thread(new LongRunningAction("thread-2", ph)).start();
new Thread(new LongRunningAction("thread-3", ph)).start();
//then
log.debug("Thread {} waiting for others", Thread.currentThread().getName());
log.info("Thread {} waiting for others", Thread.currentThread().getName());
ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
assertEquals(1, ph.getPhase());
//and
executorService.submit(new LongRunningAction("thread-4", ph));
executorService.submit(new LongRunningAction("thread-5", ph));
new Thread(new LongRunningAction("thread-4", ph)).start();
new Thread(new LongRunningAction("thread-5", ph)).start();
log.debug("Thread {} waiting for others", Thread.currentThread().getName());
log.info("Thread {} waiting for new phase", Thread.currentThread().getName());
ph.arriveAndAwaitAdvance();
log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase());
assertEquals(2, ph.getPhase());
ph.arriveAndDeregister();
Thread.sleep(1000);
assertEquals(true, ph.isTerminated());
}
}

View File

@ -38,9 +38,9 @@
<version>${fscontext.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
<groupId>org.eclipse.angus</groupId>
<artifactId>angus-activation</artifactId>
<version>${angus-activation.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -73,10 +73,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
@ -131,13 +127,15 @@
<properties>
<!-- maven plugins -->
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<hsqldb.version>2.4.0</hsqldb.version>
<maven-javadoc-plugin.version>3.5.0</maven-javadoc-plugin.version>
<hsqldb.version>2.7.1</hsqldb.version>
<!-- Mime Type Libraries -->
<tika.version>1.18</tika.version>
<tika.version>2.8.0</tika.version>
<jmime-magic.version>0.1.5</jmime-magic.version>
<maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<fscontext.version>4.4.2</fscontext.version>
<jakarta-activation-api.version>2.1.2</jakarta-activation-api.version>
<angus-activation.version>2.0.1</angus-activation.version>
</properties>
</project>

View File

@ -10,7 +10,7 @@ import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.activation.MimetypesFileTypeMap;
import jakarta.activation.MimetypesFileTypeMap;
import org.apache.tika.Tika;
import org.junit.Test;

View File

@ -33,7 +33,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google-guava.version}</version>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
@ -47,7 +47,6 @@
<commons-codec.version>1.15</commons-codec.version>
<jaxb-api.version>2.3.1</jaxb-api.version>
<spring-security-crypto.version>6.0.3</spring-security-crypto.version>
<google-guava.version>31.0.1-jre</google-guava.version>
</properties>
</project>

View File

@ -39,7 +39,7 @@
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.23.1</version>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -55,7 +55,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<version>${commons-lang3.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -81,7 +81,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google.guava.version}</version>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.oath.cyclops</groupId>
@ -114,6 +114,7 @@
<properties>
<!-- testing -->
<assertj.version>3.23.1</assertj.version>
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
@ -123,7 +124,6 @@
<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>

View File

@ -14,33 +14,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh-core.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh-generator.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.codepoetics</groupId>
<artifactId>protonpack</artifactId>
@ -57,17 +30,7 @@
<version>${streamex.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${asspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${asspectj.version}</version>
</dependency>
<dependency>
<groupId>pl.touk</groupId>
<groupId>com.pivovarit</groupId>
<artifactId>throwing-function</artifactId>
<version>${throwing-function.version}</version>
</dependency>
@ -96,15 +59,13 @@
</build>
<properties>
<vavr.version>0.9.0</vavr.version>
<protonpack.version>1.15</protonpack.version>
<streamex.version>0.6.5</streamex.version>
<joda.version>2.10</joda.version>
<throwing-function.version>1.3</throwing-function.version>
<asspectj.version>1.8.9</asspectj.version>
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<vavr.version>0.10.4</vavr.version>
<protonpack.version>1.16</protonpack.version>
<streamex.version>0.8.1</streamex.version>
<throwing-function.version>1.5.1</throwing-function.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>

View File

@ -1,8 +1,8 @@
package com.baeldung.stream.filter;
import org.junit.jupiter.api.Test;
import pl.touk.throwing.ThrowingPredicate;
import pl.touk.throwing.exception.WrappedException;
import com.pivovarit.function.ThrowingPredicate;
import com.pivovarit.function.exception.WrappedException;
import java.io.IOException;
import java.util.Arrays;
@ -156,5 +156,4 @@ public class StreamFilterUnitTest {
})
.collect(Collectors.toList())).isInstanceOf(RuntimeException.class);
}
}
}

View File

@ -22,7 +22,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang3.version}</version>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.ibm.icu</groupId>
@ -42,8 +42,6 @@
</build>
<properties>
<commons.lang3.version>3.12.0</commons.lang3.version>
<guava.version>31.1-jre</guava.version>
<icu4j.version>61.1</icu4j.version>
</properties>

View File

@ -27,7 +27,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<guava.version>31.1-jre</guava.version>
<guava.version>32.1.2-jre</guava.version>
</properties>
</project>

View File

@ -49,7 +49,7 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<guava.version>31.1-jre</guava.version>
<guava.version>32.1.2-jre</guava.version>
</properties>
</project>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.baeldung</groupId>
<artifactId>json-arrays</artifactId>
<name>json-arrays</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>json-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>${jsonb-api.version}</version>
</dependency>
</dependencies>
<properties>
<jsonb-api.version>1.0</jsonb-api.version>
<json.version>20230227</json.version>
<gson.version>2.8.5</gson.version>
<javax.version>1.1.2</javax.version>
<json-unit-assertj.version>2.28.0</json-unit-assertj.version>
</properties>
</project>

View File

@ -0,0 +1,47 @@
package com.baeldung.checkforkey;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Objects;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
public class CheckForKeyUnitTest {
private final String exampleJson = "[{\"colour\":\"red\"},{\"colour\":\"blue\"},{\"colour\":\"green\"}]";
@Test
public void givenJsonArray_whenUsingJackson_thenDetectKeyInArray() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(exampleJson);
Stream<JsonNode> s = StreamSupport.stream(tree.spliterator(), false);
boolean result = s.map(entry -> entry.get("colour"))
.filter(Objects::nonNull)
.anyMatch(colour -> "green".equals(colour.asText()));
assertTrue(result);
}
@Test
public void givenJsonArray_whenUsingGson_thenDetectKeyInArray() {
Gson gson = new Gson();
JsonArray parsed = gson.fromJson(exampleJson, JsonArray.class);
Stream<JsonElement> s = StreamSupport.stream(parsed.spliterator(), false);
boolean result = s.map(entry -> entry.getAsJsonObject()
.get("colour"))
.filter(Objects::nonNull)
.anyMatch(colour -> "green".equals(colour.getAsString()));
assertTrue(result);
}
}

View File

@ -16,6 +16,7 @@
<modules>
<module>json</module>
<module>json-2</module>
<module>json-arrays</module>
<module>json-conversion</module>
<module>json-path</module>
<module>gson</module>

View File

@ -0,0 +1,21 @@
package com.baeldung.expression.dto;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@AllArgsConstructor
@Data
@Builder
public class LicenseDto {
private UUID id;
private LocalDateTime startDate;
private LocalDateTime endDate;
}

View File

@ -0,0 +1,43 @@
package com.baeldung.expression.mapper;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import com.baeldung.expression.dto.LicenseDto;
import com.baeldung.expression.model.License;
@Mapper
public interface LicenseMapper {
@Mapping(target = "startDate", expression = "java(mapStartDate(licenseDto))")
@Mapping(target = "endDate", ignore = true)
@Mapping(target = "active", constant = "true")
@Mapping(target = "renewalRequired", conditionExpression = "java(isEndDateInTwoWeeks(licenseDto))", source = ".")
License toLicense(LicenseDto licenseDto);
@AfterMapping
default void afterMapping(LicenseDto licenseDto, @MappingTarget License license) {
OffsetDateTime endDate = licenseDto.getEndDate() != null ? licenseDto.getEndDate()
.atOffset(ZoneOffset.UTC) : OffsetDateTime.now()
.plusYears(1);
license.setEndDate(endDate);
}
default OffsetDateTime mapStartDate(LicenseDto licenseDto) {
return licenseDto.getStartDate() != null ? licenseDto.getStartDate()
.atOffset(ZoneOffset.UTC) : OffsetDateTime.now();
}
default boolean isEndDateInTwoWeeks(LicenseDto licenseDto) {
return licenseDto.getEndDate() != null && Duration.between(licenseDto.getEndDate(), LocalDateTime.now())
.toDays() <= 14;
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.expression.model;
import java.time.OffsetDateTime;
import java.util.UUID;
import lombok.Data;
@Data
public class License {
private UUID id;
private OffsetDateTime startDate;
private OffsetDateTime endDate;
private boolean active;
private boolean renewalRequired;
}

View File

@ -0,0 +1,64 @@
package com.baeldung.expression.mapper;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
import com.baeldung.expression.dto.LicenseDto;
import com.baeldung.expression.model.License;
class LicenseMapperUnitTest {
LicenseMapper licenseMapper = Mappers.getMapper(LicenseMapper.class);
@Test
void givenLicenseDtoWithStartDateAndWithoutEndDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultEndDate() {
License license = licenseMapper.toLicense(LicenseDto.builder()
.startDate(LocalDateTime.now())
.build());
assertThat(license).isNotNull();
assertThat(license.getEndDate()
.toLocalDate()).isEqualTo(LocalDate.now()
.plusYears(1));
}
@Test
void givenLicenseDtoWithEndDateAndWithoutStartDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultStartDate() {
License license = licenseMapper.toLicense(LicenseDto.builder()
.endDate(LocalDateTime.now()
.plusYears(2))
.build());
assertThat(license).isNotNull();
assertThat(license.getStartDate()
.toLocalDate()).isEqualTo(LocalDate.now());
}
@Test
void givenLicenseDtoWithoutStartDateAndEndDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultDetails() {
License license = licenseMapper.toLicense(LicenseDto.builder()
.build());
assertThat(license).isNotNull();
assertThat(license.getStartDate()
.toLocalDate()).isEqualTo(LocalDate.now());
assertThat(license.getEndDate()
.toLocalDate()).isEqualTo(LocalDate.now()
.plusYears(1));
assertThat(license.isActive()).isTrue();
assertThat(license.isRenewalRequired()).isFalse();
}
@Test
void givenLicenseDtoWithEndDateInTwoWeeks_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithRenewalRequiredSetToTrue() {
License license = licenseMapper.toLicense(LicenseDto.builder()
.endDate(LocalDateTime.now()
.plusDays(10))
.build());
assertThat(license).isNotNull();
assertThat(license.isRenewalRequired()).isTrue();
}
}

View File

@ -1300,7 +1300,7 @@
<maven-pmd-plugin.version>3.19.0</maven-pmd-plugin.version>
<lombok.version>1.18.28</lombok.version>
<h2.version>2.1.214</h2.version>
<guava.version>31.1-jre</guava.version>
<guava.version>32.1.2-jre</guava.version>
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
</properties>

View File

@ -26,7 +26,7 @@
<module>jee-7</module>
<module>jooby</module>
<module>linkrest</module>
<!-- <module>ninja</module> --> <!-- JAVA-22066 -->
<module>ninja</module>
<!-- <module>play-modules</module> --> <!-- Not a maven project -->
<!-- <module>raml-modules</module> --> <!-- Not a maven project -->
<module>ratpack</module>