Merge branch 'master' into JAVA-25997
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>apache-poi-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aws-s3-update-object</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>aws-s3-update-object</name>
|
||||
<description>Project demonstrating overwriting of S3 objects</description>
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk</artifactId>
|
||||
<version>${aws-java-sdk-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
<aws-java-sdk-version>1.12.523</aws-java-sdk-version>
|
||||
</properties>
|
||||
</project>
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package com.baeldung.awss3updateobject;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AwsS3UpdateObjectApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AwsS3UpdateObjectApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package com.baeldung.awss3updateobject.controller;
|
||||
|
||||
import com.baeldung.awss3updateobject.service.FileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/v1/file")
|
||||
public class FileController {
|
||||
|
||||
@Autowired
|
||||
FileService fileService;
|
||||
|
||||
@PostMapping("/upload")
|
||||
public String uploadFile(@RequestParam("file") MultipartFile multipartFile) throws Exception {
|
||||
return this.fileService.uploadFile(multipartFile);
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public String updateFile(@RequestParam("file") MultipartFile multipartFile, @RequestParam("filePath") String exitingFilePath) throws Exception {
|
||||
return this.fileService.updateFile(multipartFile, exitingFilePath);
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
package com.baeldung.awss3updateobject.service;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentials;
|
||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
||||
import com.amazonaws.services.s3.model.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class FileService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileService.class);
|
||||
|
||||
public AmazonS3 amazonS3;
|
||||
|
||||
@Value("${aws.s3bucket}")
|
||||
public String awsS3Bucket;
|
||||
|
||||
@PostConstruct
|
||||
private void init(){
|
||||
AWSCredentials credentials = new BasicAWSCredentials(
|
||||
"AWS AccessKey",
|
||||
"AWS secretKey"
|
||||
);
|
||||
this.amazonS3 = AmazonS3ClientBuilder.standard()
|
||||
.withRegion(Regions.fromName("us-east-1"))
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.build();
|
||||
}
|
||||
|
||||
public String uploadFile(MultipartFile multipartFile) throws Exception {
|
||||
String key = "/documents/" + multipartFile.getOriginalFilename();
|
||||
return this.uploadDocument(this.awsS3Bucket, key, multipartFile);
|
||||
}
|
||||
|
||||
public String updateFile(MultipartFile multipartFile, String key) throws Exception {
|
||||
return this.uploadDocument(this.awsS3Bucket, key, multipartFile);
|
||||
}
|
||||
|
||||
private String uploadDocument(String s3bucket, String key, MultipartFile multipartFile) throws Exception {
|
||||
try {
|
||||
ObjectMetadata metadata = new ObjectMetadata();
|
||||
metadata.setContentType(multipartFile.getContentType());
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("document-content-size", String.valueOf(multipartFile.getSize()));
|
||||
metadata.setUserMetadata(attributes);
|
||||
InputStream documentStream = multipartFile.getInputStream();
|
||||
PutObjectResult putObjectResult = this.amazonS3.putObject(new PutObjectRequest(s3bucket, key, documentStream, metadata));
|
||||
|
||||
S3Object s3Object = this.amazonS3.getObject(s3bucket, key);
|
||||
logger.info("Last Modified: " + s3Object.getObjectMetadata().getLastModified());
|
||||
return key;
|
||||
} catch (AmazonS3Exception ex) {
|
||||
if (ex.getErrorCode().equalsIgnoreCase("NoSuchBucket")) {
|
||||
String msg = String.format("No bucket found with name %s", s3bucket);
|
||||
throw new Exception(msg);
|
||||
} else if (ex.getErrorCode().equalsIgnoreCase("AccessDenied")) {
|
||||
String msg = String.format("Access denied to S3 bucket %s", s3bucket);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
throw ex;
|
||||
} catch (IOException ex) {
|
||||
String msg = String.format("Error saving file %s to AWS S3 bucket %s", key, s3bucket);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
aws.s3bucket=baeldung-documents;
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
package com.baeldung.awss3updateobject.controller;
|
||||
|
||||
import com.baeldung.awss3updateobject.service.FileService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
|
||||
public class FileControllerUnitTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Mock
|
||||
private FileService fileService;
|
||||
|
||||
@InjectMocks
|
||||
private FileController fileController;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
this.mockMvc = MockMvcBuilders.standaloneSetup(fileController).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidMultipartFile_whenUploadedViaEndpoint_thenCorrectPathIsReturned() throws Exception {
|
||||
MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt", "text/plain", "sample file content".getBytes());
|
||||
String expectedResult = "File Uploaded Successfully";
|
||||
|
||||
when(fileService.uploadFile(multipartFile)).thenReturn(expectedResult);
|
||||
|
||||
mockMvc.perform(multipart("/api/v1/file/upload").file(multipartFile))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(expectedResult));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidMultipartFileAndExistingPath_whenUpdatedViaEndpoint_thenSamePathIsReturned() throws Exception {
|
||||
MockMultipartFile multipartFile = new MockMultipartFile("file", "test.txt", "text/plain", "updated file content".getBytes());
|
||||
String filePath = "some/path/to/file";
|
||||
String expectedResult = "File Updated Successfully";
|
||||
|
||||
when(fileService.updateFile(multipartFile, filePath)).thenReturn(expectedResult);
|
||||
|
||||
mockMvc.perform(multipart("/api/v1/file/update")
|
||||
.file(multipartFile)
|
||||
.param("filePath", filePath))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(expectedResult));
|
||||
}
|
||||
}
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
package com.baeldung.awss3updateobject.service;
|
||||
|
||||
import com.amazonaws.services.s3.AmazonS3;
|
||||
import com.amazonaws.services.s3.model.AmazonS3Exception;
|
||||
import com.amazonaws.services.s3.model.PutObjectRequest;
|
||||
import com.amazonaws.services.s3.model.S3Object;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class FileServiceUnitTest {
|
||||
|
||||
@Mock
|
||||
private AmazonS3 amazonS3;
|
||||
|
||||
@Mock
|
||||
private MultipartFile multipartFile;
|
||||
|
||||
@InjectMocks
|
||||
private FileService fileService;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
fileService = new FileService();
|
||||
fileService.awsS3Bucket = "test-bucket";
|
||||
fileService.amazonS3 = amazonS3;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidFile_whenUploaded_thenKeyMatchesDocumentPath() throws Exception {
|
||||
when(multipartFile.getName()).thenReturn("testFile");
|
||||
when(multipartFile.getOriginalFilename()).thenReturn("testFile");
|
||||
when(multipartFile.getContentType()).thenReturn("application/pdf");
|
||||
when(multipartFile.getSize()).thenReturn(1024L);
|
||||
when(multipartFile.getInputStream()).thenReturn(mock(InputStream.class));
|
||||
|
||||
S3Object s3Object = new S3Object();
|
||||
when(amazonS3.putObject(any())).thenReturn(null);
|
||||
when(amazonS3.getObject(anyString(), anyString())).thenReturn(s3Object);
|
||||
|
||||
String key = fileService.uploadFile(multipartFile);
|
||||
|
||||
assertEquals("/documents/testFile", key);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidFile_whenUploadFailsDueToNoBucket_thenExceptionIsThrown() throws Exception {
|
||||
when(multipartFile.getName()).thenReturn("testFile");
|
||||
when(multipartFile.getOriginalFilename()).thenReturn("testFile");
|
||||
when(multipartFile.getContentType()).thenReturn("application/pdf");
|
||||
when(multipartFile.getSize()).thenReturn(1024L);
|
||||
when(multipartFile.getInputStream()).thenReturn(mock(InputStream.class));
|
||||
|
||||
AmazonS3Exception exception = new AmazonS3Exception("Test exception");
|
||||
exception.setErrorCode("NoSuchBucket");
|
||||
when(amazonS3.putObject(any(PutObjectRequest.class))).thenThrow(exception);
|
||||
|
||||
assertThrows(Exception.class, () -> fileService.uploadFile(multipartFile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExistingFile_whenUpdated_thenSameKeyIsReturned() throws Exception {
|
||||
when(multipartFile.getName()).thenReturn("testFile");
|
||||
when(multipartFile.getContentType()).thenReturn("application/pdf");
|
||||
when(multipartFile.getSize()).thenReturn(1024L);
|
||||
when(multipartFile.getInputStream()).thenReturn(mock(InputStream.class));
|
||||
|
||||
S3Object s3Object = new S3Object();
|
||||
when(amazonS3.putObject(any(PutObjectRequest.class))).thenReturn(null);
|
||||
when(amazonS3.getObject(anyString(), anyString())).thenReturn(s3Object);
|
||||
|
||||
String key = "/documents/existingFile";
|
||||
String resultKey = fileService.updateFile(multipartFile, key);
|
||||
|
||||
assertEquals(key, resultKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFileWithIOException_whenUpdated_thenExceptionIsThrown() throws Exception {
|
||||
when(multipartFile.getName()).thenReturn("testFile");
|
||||
when(multipartFile.getContentType()).thenReturn("application/pdf");
|
||||
when(multipartFile.getSize()).thenReturn(1024L);
|
||||
when(multipartFile.getInputStream()).thenThrow(new IOException("Test IO Exception"));
|
||||
|
||||
assertThrows(Exception.class, () -> fileService.updateFile(multipartFile, "/documents/existingFile"));
|
||||
}
|
||||
}
|
||||
@@ -11,3 +11,4 @@ This module contains articles about Simple Storage Service (S3) on AWS
|
||||
- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects)
|
||||
- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object)
|
||||
- [How To Rename Files and Folders in Amazon S3](https://www.baeldung.com/java-amazon-s3-rename-files-folders)
|
||||
- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object)
|
||||
|
||||
@@ -45,6 +45,13 @@ public class S3Application {
|
||||
new File("/Users/user/Document/hello.txt")
|
||||
);
|
||||
|
||||
s3Service.updateObject(
|
||||
AWS_BUCKET,
|
||||
"Document/hello2.txt",
|
||||
new File("/Users/user/Document/hello2.txt")
|
||||
);
|
||||
|
||||
|
||||
//listing objects
|
||||
s3Service.listObjects(AWS_BUCKET);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
||||
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
|
||||
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
|
||||
@@ -99,7 +100,13 @@ class S3Service {
|
||||
.key(key)
|
||||
.build();
|
||||
|
||||
return s3Client.putObject(request, Path.of(file.toURI()) );
|
||||
|
||||
return s3Client.putObject(request, Path.of(file.toURI()));
|
||||
}
|
||||
|
||||
//updating object
|
||||
public PutObjectResponse updateObject(String bucketName, String key, java.io.File file) {
|
||||
return this.putObject(bucketName, key, file);
|
||||
}
|
||||
|
||||
//listing objects
|
||||
@@ -110,6 +117,7 @@ class S3Service {
|
||||
ListObjectsV2Response listObjectsV2Response = s3Client.listObjectsV2(listObjectsV2Request);
|
||||
|
||||
for(S3Object os : listObjectsV2Response.contents()) {
|
||||
|
||||
System.out.println(os.key());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
@@ -23,6 +25,7 @@ import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
|
||||
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
|
||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||
|
||||
class S3ServiceIntegrationTest {
|
||||
|
||||
@@ -38,6 +41,8 @@ class S3ServiceIntegrationTest {
|
||||
|
||||
private final String AWS_BUCKET = "baeldung-tutorial-s3";
|
||||
|
||||
private File file = new File("/Users/user/Document/hello2.txt");
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
@@ -75,6 +80,17 @@ class S3ServiceIntegrationTest {
|
||||
verify(s3Client).createBucket(bucketRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenVerifyingUploadOfS3Object_thenCorrect() {
|
||||
PutObjectRequest request = PutObjectRequest.builder()
|
||||
.bucket(BUCKET_NAME)
|
||||
.key(KEY_NAME)
|
||||
.build();
|
||||
|
||||
s3Service.putObject(BUCKET_NAME, KEY_NAME, file);
|
||||
verify(s3Client).putObject(request, Path.of(file.toURI()) );
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenVerifyingListBuckets_thenCorrect() {
|
||||
when(s3Client.listBuckets()).thenReturn(ListBucketsResponse.builder().buckets(Collections.emptyList()).build());
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
<module>aws-miscellaneous</module>
|
||||
<module>aws-reactive</module>
|
||||
<module>aws-s3</module>
|
||||
<module>aws-s3-update-object</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -21,30 +21,8 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source.version}</source>
|
||||
<target>${maven.compiler.target.version}</target>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>--enable-preview</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>12</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>12</maven.compiler.target.version>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
-13
@@ -19,19 +19,6 @@ public class SwitchUnitTest {
|
||||
Assert.assertEquals(value, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void switchLocalVariable(){
|
||||
var month = Month.AUG;
|
||||
int i = switch (month){
|
||||
case JAN,JUN, JUL -> 3;
|
||||
case FEB,SEP, OCT, NOV, DEC -> 1;
|
||||
case MAR,MAY, APR, AUG -> {
|
||||
int j = month.toString().length() * 4;
|
||||
break j;
|
||||
}
|
||||
};
|
||||
Assert.assertEquals(12, i);
|
||||
}
|
||||
|
||||
enum Month {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}
|
||||
}
|
||||
|
||||
@@ -8,39 +8,13 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source.version}</source>
|
||||
<target>${maven.compiler.target.version}</target>
|
||||
<release>13</release>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire.plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>--enable-preview</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>13</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>13</maven.compiler.target.version>
|
||||
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
-1
@@ -7,7 +7,6 @@ import org.junit.Test;
|
||||
public class SwitchExpressionsWithYieldUnitTest {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("preview")
|
||||
public void whenSwitchingOnOperationSquareMe_thenWillReturnSquare() {
|
||||
var me = 4;
|
||||
var operation = "squareMe";
|
||||
|
||||
-2
@@ -8,7 +8,6 @@ public class TextBlocksUnitTest {
|
||||
|
||||
private static final String JSON_STRING = "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"https://www.%s.com/\"\r\n" + "}";
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
private static final String TEXT_BLOCK_JSON = """
|
||||
{
|
||||
"name" : "Baeldung",
|
||||
@@ -25,7 +24,6 @@ public class TextBlocksUnitTest {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
@Test
|
||||
public void whenTextBlocks_thenFormattedWorksAsFormat() {
|
||||
assertThat(TEXT_BLOCK_JSON.formatted("baeldung")
|
||||
|
||||
-4
@@ -13,7 +13,6 @@ import org.junit.Test;
|
||||
public class SwitchExpressionsUnitTest {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings ("preview")
|
||||
public void whenSwitchingOverMonthJune_thenWillReturn3() {
|
||||
|
||||
var month = JUNE;
|
||||
@@ -29,7 +28,6 @@ public class SwitchExpressionsUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings ("preview")
|
||||
public void whenSwitchingOverMonthAugust_thenWillReturn24() {
|
||||
var month = AUGUST;
|
||||
|
||||
@@ -47,7 +45,6 @@ public class SwitchExpressionsUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings ("preview")
|
||||
public void whenSwitchingOverMonthJanuary_thenWillReturn3() {
|
||||
|
||||
Function<Month, Integer> func = (month) -> {
|
||||
@@ -61,7 +58,6 @@ public class SwitchExpressionsUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings ("preview")
|
||||
public void whenSwitchingOverMonthAugust_thenWillReturn2() {
|
||||
var month = AUGUST;
|
||||
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -27,33 +26,8 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<release>${maven.compiler.release}</release>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>14</source>
|
||||
<target>14</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire.plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>--enable-preview</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.release>15</maven.compiler.release>
|
||||
<surefire.plugin.version>3.0.0-M3</surefire.plugin.version>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-21</artifactId>
|
||||
<name>core-java-21</name>
|
||||
@@ -12,12 +12,6 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>21</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>21</maven.compiler.target.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -44,4 +38,10 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>21</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>21</maven.compiler.target.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-arrays-operations-advanced-2</artifactId>
|
||||
<name>core-java-arrays-operations-advanced-2</name>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-collections-array-list-2</artifactId>
|
||||
<name>core-java-collections-array-list-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -24,7 +24,7 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<properties>
|
||||
<maven-compiler-plugin.source>17</maven-compiler-plugin.source>
|
||||
<maven-compiler-plugin.target>17</maven-compiler-plugin.target>
|
||||
|
||||
+12
-1
@@ -71,4 +71,15 @@ public class ListOfListsUnitTest {
|
||||
assertThat(listOfLists.get(2)).containsExactly("Slack", "Zoom", "Microsoft Teams", "Telegram");
|
||||
printListOfLists(listOfLists);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenListOfLists_whenGettingSizeOfSubListsAndSizeOfElements_thenGetExpectedResults() throws URISyntaxException, IOException {
|
||||
List<List<String>> listOfLists = getListOfListsFromCsv();
|
||||
// size of inner lists
|
||||
assertThat(listOfLists).hasSize(3);
|
||||
|
||||
// size of all elements in subLists
|
||||
int totalElements = listOfLists.stream().mapToInt(List::size).sum();
|
||||
assertThat(totalElements).isEqualTo(12);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?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">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-collections-list-6</artifactId>
|
||||
<name>core-java-collections-list-6</name>
|
||||
@@ -12,4 +12,5 @@
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
||||
@@ -73,6 +73,11 @@
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.baeldung.map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class Magic {
|
||||
public String nullFunc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String strFunc(String input) {
|
||||
return input + ": A nice string";
|
||||
}
|
||||
}
|
||||
|
||||
public class PutIfAbsentVsComputeIfAbsentUnitTest {
|
||||
|
||||
private static final Map<String, String> MY_MAP = new HashMap<>();
|
||||
private Magic magic = new Magic();
|
||||
|
||||
@BeforeEach
|
||||
void resetTheMap() {
|
||||
MY_MAP.clear();
|
||||
MY_MAP.put("Key A", "value A");
|
||||
MY_MAP.put("Key B", "value B");
|
||||
MY_MAP.put("Key C", "value C");
|
||||
MY_MAP.put("Key Null", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingPutIfAbsentWithAbsentKey_thenGetNull() {
|
||||
String putResult = MY_MAP.putIfAbsent("new key1", magic.nullFunc());
|
||||
assertNull(putResult);
|
||||
|
||||
putResult = MY_MAP.putIfAbsent("new key2", magic.strFunc("new key2"));
|
||||
assertNull(putResult);
|
||||
|
||||
putResult = MY_MAP.putIfAbsent("Key Null", magic.strFunc("Key Null"));
|
||||
assertNull(putResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingComputeIfAbsentWithAbsentKey_thenGetExpectedResult() {
|
||||
String computeResult = MY_MAP.computeIfAbsent("new key1", k -> magic.nullFunc());
|
||||
assertNull(computeResult);
|
||||
|
||||
computeResult = MY_MAP.computeIfAbsent("new key2", k -> magic.strFunc(k));
|
||||
assertEquals("new key2: A nice string", computeResult);
|
||||
|
||||
computeResult = MY_MAP.computeIfAbsent("Key Null", k -> magic.strFunc(k));
|
||||
assertEquals("Key Null: A nice string", computeResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingPutIfAbsentWithAbsentKey_thenNullIsPut() {
|
||||
assertEquals(4, MY_MAP.size()); // initial: 4 entries
|
||||
MY_MAP.putIfAbsent("new key", magic.nullFunc());
|
||||
assertEquals(5, MY_MAP.size());
|
||||
assertTrue(MY_MAP.containsKey("new key")); // new entry has been added to the map
|
||||
assertNull(MY_MAP.get("new key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingComputeIfAbsentWithAbsentKey_thenNullIsNotPut() {
|
||||
assertEquals(4, MY_MAP.size()); // initial: 4 entries
|
||||
MY_MAP.computeIfAbsent("new key", k -> magic.nullFunc());
|
||||
assertEquals(4, MY_MAP.size());
|
||||
assertFalse(MY_MAP.containsKey("new key")); // <- no new entry added
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingPutIfAbsent_thenFunctionIsAlwaysCalled() {
|
||||
Magic spyMagic = spy(magic);
|
||||
MY_MAP.putIfAbsent("Key A", spyMagic.strFunc("Key A"));
|
||||
verify(spyMagic, times(1)).strFunc(anyString());
|
||||
|
||||
MY_MAP.putIfAbsent("new key", spyMagic.strFunc("new key"));
|
||||
verify(spyMagic, times(2)).strFunc(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCallingComputeIfAbsent_thenFunctionIsCalledOnDemand() {
|
||||
Magic spyMagic = spy(magic);
|
||||
MY_MAP.computeIfAbsent("Key A", k -> spyMagic.strFunc(k));
|
||||
verify(spyMagic, never()).strFunc(anyString());
|
||||
|
||||
MY_MAP.computeIfAbsent("new key", k -> spyMagic.strFunc(k));
|
||||
verify(spyMagic, times(1)).strFunc(anyString());
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.baeldung.writehashmaptocsvfile;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class WriteHashmaptoCVSFileUnitTest {
|
||||
public Map<String, String> employeeData;
|
||||
|
||||
public WriteHashmaptoCVSFileUnitTest() {
|
||||
employeeData = new HashMap<>();
|
||||
employeeData.put("Name", "John Doe");
|
||||
employeeData.put("Title", "Software Engineer");
|
||||
employeeData.put("Department", "Engineering");
|
||||
employeeData.put("Salary", "75000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmployeeData_whenWriteToCSVUsingFileWriter_thenCSVFileIsCreated() {
|
||||
|
||||
try (FileWriter csvWriter = new FileWriter("employee_data.csv")) {
|
||||
// Write header row
|
||||
csvWriter.append("Name,Title,Department,Salary\n");
|
||||
|
||||
// Write data row
|
||||
csvWriter.append(employeeData.get("Name")).append(",");
|
||||
csvWriter.append(employeeData.get("Title")).append(",");
|
||||
csvWriter.append(employeeData.get("Department")).append(",");
|
||||
csvWriter.append(employeeData.get("Salary")).append("\n");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Ensure the CSV file exists
|
||||
assertTrue(new File("employee_data.csv").exists(), "CSV file does not exist!");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCSVFile_whenWriteToCSVUsingApacheCommons_thenContentsMatchExpected() {
|
||||
|
||||
try (CSVPrinter csvPrinter = new CSVPrinter(new FileWriter("employee_data2.csv"), CSVFormat.DEFAULT)) {
|
||||
// Write header row
|
||||
csvPrinter.printRecord("Name", "Title", "Department", "Salary");
|
||||
|
||||
// Write data row
|
||||
csvPrinter.printRecord(employeeData.get("Name"), employeeData.get("Title"), employeeData.get("Department"), employeeData.get("Salary"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Ensure the CSV file exists
|
||||
assertTrue(new File("employee_data2.csv").exists());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-concurrency-advanced-5</artifactId>
|
||||
<name>core-java-concurrency-advanced-5</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-concurrency-advanced-5</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.wait_synchronization;
|
||||
|
||||
public class ConditionChecker {
|
||||
|
||||
private volatile Boolean jobIsDone;
|
||||
private final Object lock = new Object();
|
||||
|
||||
public void ensureCondition() {
|
||||
synchronized (lock) {
|
||||
while (!jobIsDone) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void complete() {
|
||||
synchronized (lock) {
|
||||
jobIsDone = true;
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user