Merge branch 'eugenp:master' into master
This commit is contained in:
commit
3c895d237e
3
.gitignore
vendored
3
.gitignore
vendored
@ -65,6 +65,9 @@ core-java-io/target_link.txt
|
||||
core-java/src/main/java/com/baeldung/manifest/MANIFEST.MF
|
||||
ethereum/logs/
|
||||
jmeter/src/main/resources/*-JMeter.csv
|
||||
jmeter/src/main/resources/*-Basic*.csv
|
||||
jmeter/src/main/resources/*-JMeter*.csv
|
||||
|
||||
ninja/devDb.mv.db
|
||||
|
||||
**/node_modules/
|
||||
|
@ -4,4 +4,5 @@
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [Guide to In-Place Sorting Algorithm Works with a Java Implementation](https://www.baeldung.com/java-in-place-sorting)
|
||||
- [Partitioning and Sorting Arrays with Many Repeated Entries with Java Examples](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
|
||||
- [Gravity/Bead Sort in Java](https://www.baeldung.com/java-gravity-bead-sort)
|
||||
- More articles: [[<-- prev]](/algorithms-sorting)
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.baeldung.algorithms.gravitysort;
|
||||
|
||||
public class GravitySort {
|
||||
|
||||
public static int findMax(int[] A) {
|
||||
int max = A[0];
|
||||
for (int i = 1; i< A.length; i++) {
|
||||
if (A[i] > max) {
|
||||
max = A[i];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static boolean[][] setupAbacus(int[] A, int m) {
|
||||
boolean[][] abacus = new boolean[A.length][m];
|
||||
for (int i = 0; i < abacus.length; i++) {
|
||||
int number = A[i];
|
||||
for (int j = 0; j < abacus[0].length && j < number; j++) {
|
||||
abacus[A.length - 1 - i][j] = true;
|
||||
}
|
||||
}
|
||||
return abacus;
|
||||
}
|
||||
|
||||
public static void dropBeads(boolean[][] abacus, int[] A, int m) {
|
||||
for (int i = 1; i < A.length; i++) {
|
||||
for (int j = m - 1; j >= 0; j--) {
|
||||
if (abacus[i][j] == true) {
|
||||
int x = i;
|
||||
while (x > 0 && abacus[x - 1][j] == false) {
|
||||
boolean temp = abacus[x - 1][j];
|
||||
abacus[x - 1][j] = abacus[x][j];
|
||||
abacus[x][j] = temp;
|
||||
x--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void transformToList(boolean[][] abacus, int[] A) {
|
||||
int index = 0;
|
||||
for (int i = abacus.length - 1; i >= 0; i--) {
|
||||
int beads = 0;
|
||||
for (int j = 0; j < abacus[0].length && abacus[i][j] == true; j++) {
|
||||
beads++;
|
||||
}
|
||||
A[index++] = beads;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sort(int[] A) {
|
||||
int m = findMax(A);
|
||||
boolean[][] abacus = setupAbacus(A, m);
|
||||
dropBeads(abacus, A, m);
|
||||
// transform abacus into sorted list
|
||||
transformToList(abacus, A);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baeldung.algorithms.gravitysort;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GravitySortUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenIntegerArray_whenSortedWithGravitySort_thenGetSortedArray() {
|
||||
int[] actual = { 9, 9, 100, 3, 57, 12, 3, 78, 0, 2, 2, 40, 21, 9 };
|
||||
int[] expected = { 0, 2, 2, 3, 3, 9, 9, 9, 12, 21, 40, 57, 78, 100 };
|
||||
GravitySort.sort(actual);
|
||||
Assert.assertArrayEquals(expected, actual);
|
||||
}
|
||||
}
|
@ -95,8 +95,8 @@
|
||||
|
||||
<properties>
|
||||
<json-simple.version>1.1.1</json-simple.version>
|
||||
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
||||
<aws-lambda-java-core.version>1.2.0</aws-lambda-java-core.version>
|
||||
<aws-lambda-java-events.version>3.11.0</aws-lambda-java-events.version>
|
||||
<aws-lambda-java-core.version>1.2.1</aws-lambda-java-core.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
</properties>
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package com.baeldung.lambda.dynamodb;
|
||||
|
||||
import com.amazonaws.regions.Region;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
|
||||
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
|
||||
import com.amazonaws.services.dynamodbv2.document.Item;
|
||||
import com.amazonaws.services.dynamodbv2.document.PutItemOutcome;
|
||||
import com.amazonaws.services.dynamodbv2.document.spec.PutItemSpec;
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
|
||||
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
|
||||
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
|
||||
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
|
||||
import com.amazonaws.services.lambda.runtime.Context;
|
||||
import com.amazonaws.services.lambda.runtime.RequestHandler;
|
||||
@ -15,7 +15,7 @@ import com.baeldung.lambda.dynamodb.bean.PersonResponse;
|
||||
|
||||
public class SavePersonHandler implements RequestHandler<PersonRequest, PersonResponse> {
|
||||
|
||||
private DynamoDB dynamoDb;
|
||||
private AmazonDynamoDB amazonDynamoDB;
|
||||
|
||||
private String DYNAMODB_TABLE_NAME = "Person";
|
||||
private Regions REGION = Regions.US_WEST_2;
|
||||
@ -30,20 +30,22 @@ public class SavePersonHandler implements RequestHandler<PersonRequest, PersonRe
|
||||
return personResponse;
|
||||
}
|
||||
|
||||
private PutItemOutcome persistData(PersonRequest personRequest) throws ConditionalCheckFailedException {
|
||||
return this.dynamoDb.getTable(DYNAMODB_TABLE_NAME)
|
||||
.putItem(
|
||||
new PutItemSpec().withItem(new Item()
|
||||
.withNumber("id", personRequest.getId())
|
||||
.withString("firstName", personRequest.getFirstName())
|
||||
.withString("lastName", personRequest.getLastName())
|
||||
.withNumber("age", personRequest.getAge())
|
||||
.withString("address", personRequest.getAddress())));
|
||||
private void persistData(PersonRequest personRequest) throws ConditionalCheckFailedException {
|
||||
|
||||
Map<String, AttributeValue> attributesMap = new HashMap<>();
|
||||
|
||||
attributesMap.put("id", new AttributeValue(String.valueOf(personRequest.getId())));
|
||||
attributesMap.put("firstName", new AttributeValue(personRequest.getFirstName()));
|
||||
attributesMap.put("lastName", new AttributeValue(personRequest.getLastName()));
|
||||
attributesMap.put("age", new AttributeValue(String.valueOf(personRequest.getAge())));
|
||||
attributesMap.put("address", new AttributeValue(personRequest.getAddress()));
|
||||
|
||||
amazonDynamoDB.putItem(DYNAMODB_TABLE_NAME, attributesMap);
|
||||
}
|
||||
|
||||
private void initDynamoDbClient() {
|
||||
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
|
||||
client.setRegion(Region.getRegion(REGION));
|
||||
this.dynamoDb = new DynamoDB(client);
|
||||
this.amazonDynamoDB = AmazonDynamoDBClientBuilder.standard()
|
||||
.withRegion(REGION)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@
|
||||
|
||||
<properties>
|
||||
<spring.version>2.2.1.RELEASE</spring.version>
|
||||
<awssdk.version>2.10.27</awssdk.version>
|
||||
<awssdk.version>2.17.283</awssdk.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -3,17 +3,11 @@
|
||||
*/
|
||||
package com.baeldung.aws.reactive.s3;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.ResponseEntity.BodyBuilder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -22,11 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import software.amazon.awssdk.core.ResponseBytes;
|
||||
import software.amazon.awssdk.core.SdkResponse;
|
||||
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
|
||||
import software.amazon.awssdk.core.async.SdkPublisher;
|
||||
import software.amazon.awssdk.core.internal.async.ByteArrayAsyncResponseTransformer;
|
||||
import software.amazon.awssdk.http.SdkHttpResponse;
|
||||
import software.amazon.awssdk.services.s3.S3AsyncClient;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||
@ -40,38 +30,39 @@ import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
||||
@RequestMapping("/inbox")
|
||||
@Slf4j
|
||||
public class DownloadResource {
|
||||
|
||||
|
||||
|
||||
private final S3AsyncClient s3client;
|
||||
private final S3ClientConfigurarionProperties s3config;
|
||||
|
||||
public DownloadResource(S3AsyncClient s3client, S3ClientConfigurarionProperties s3config) {
|
||||
this.s3client = s3client;
|
||||
this.s3config = s3config;
|
||||
this.s3config = s3config;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(path="/{filekey}")
|
||||
public Mono<ResponseEntity<Flux<ByteBuffer>>> downloadFile(@PathVariable("filekey") String filekey) {
|
||||
|
||||
GetObjectRequest request = GetObjectRequest.builder()
|
||||
.bucket(s3config.getBucket())
|
||||
.key(filekey)
|
||||
.build();
|
||||
|
||||
return Mono.fromFuture(s3client.getObject(request,new FluxResponseProvider()))
|
||||
.map( (response) -> {
|
||||
checkResult(response.sdkResponse);
|
||||
String filename = getMetadataItem(response.sdkResponse,"filename",filekey);
|
||||
|
||||
log.info("[I65] filename={}, length={}",filename, response.sdkResponse.contentLength() );
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_TYPE, response.sdkResponse.contentType())
|
||||
.header(HttpHeaders.CONTENT_LENGTH, Long.toString(response.sdkResponse.contentLength()))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
|
||||
.body(response.flux);
|
||||
});
|
||||
@GetMapping(path = "/{filekey}")
|
||||
public Mono<ResponseEntity<Flux<ByteBuffer>>> downloadFile(@PathVariable("filekey") String filekey) {
|
||||
|
||||
GetObjectRequest request = GetObjectRequest.builder()
|
||||
.bucket(s3config.getBucket())
|
||||
.key(filekey)
|
||||
.build();
|
||||
|
||||
return Mono.fromFuture(s3client.getObject(request, AsyncResponseTransformer.toPublisher()))
|
||||
.map(response -> {
|
||||
checkResult(response.response());
|
||||
String filename = getMetadataItem(response.response(), "filename", filekey);
|
||||
|
||||
log.info("[I65] filename={}, length={}", filename, response.response()
|
||||
.contentLength());
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_TYPE, response.response()
|
||||
.contentType())
|
||||
.header(HttpHeaders.CONTENT_LENGTH, Long.toString(response.response()
|
||||
.contentLength()))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
|
||||
.body(Flux.from(response));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,63 +73,24 @@ public class DownloadResource {
|
||||
* @return
|
||||
*/
|
||||
private String getMetadataItem(GetObjectResponse sdkResponse, String key, String defaultValue) {
|
||||
for( Entry<String, String> entry : sdkResponse.metadata().entrySet()) {
|
||||
if ( entry.getKey().equalsIgnoreCase(key)) {
|
||||
for (Entry<String, String> entry : sdkResponse.metadata()
|
||||
.entrySet()) {
|
||||
if (entry.getKey()
|
||||
.equalsIgnoreCase(key)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
// Helper used to check return codes from an API call
|
||||
private static void checkResult(GetObjectResponse response) {
|
||||
SdkHttpResponse sdkResponse = response.sdkHttpResponse();
|
||||
if ( sdkResponse != null && sdkResponse.isSuccessful()) {
|
||||
if (sdkResponse != null && sdkResponse.isSuccessful()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
throw new DownloadFailedException(response);
|
||||
}
|
||||
|
||||
|
||||
static class FluxResponseProvider implements AsyncResponseTransformer<GetObjectResponse,FluxResponse> {
|
||||
|
||||
private FluxResponse response;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<FluxResponse> prepare() {
|
||||
response = new FluxResponse();
|
||||
return response.cf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(GetObjectResponse sdkResponse) {
|
||||
this.response.sdkResponse = sdkResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStream(SdkPublisher<ByteBuffer> publisher) {
|
||||
response.flux = Flux.from(publisher);
|
||||
response.cf.complete(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionOccurred(Throwable error) {
|
||||
response.cf.completeExceptionally(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds the API response and stream
|
||||
* @author Philippe
|
||||
*/
|
||||
static class FluxResponse {
|
||||
|
||||
final CompletableFuture<FluxResponse> cf = new CompletableFuture<>();
|
||||
GetObjectResponse sdkResponse;
|
||||
Flux<ByteBuffer> flux;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<aws-java-sdk.version>1.11.290</aws-java-sdk.version>
|
||||
<aws-java-sdk.version>1.12.331</aws-java-sdk.version>
|
||||
<maven-shade-plugin.version>3.0.0</maven-shade-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
@ -13,4 +13,4 @@ One script is included to easily start middleware using Docker:
|
||||
- [A Guide to the Axon Framework](https://www.baeldung.com/axon-cqrs-event-sourcing)
|
||||
- [Multi-Entity Aggregates in Axon](https://www.baeldung.com/java-axon-multi-entity-aggregates)
|
||||
- [Snapshotting Aggregates in Axon](https://www.baeldung.com/axon-snapshotting-aggregates)
|
||||
- [Dispatching Queries in Axon Framework](https://www.baeldung.com/axon-query-dispatching/)
|
||||
- [Dispatching Queries in Axon Framework](https://www.baeldung.com/axon-query-dispatching)
|
||||
|
@ -3,7 +3,10 @@
|
||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
||||
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
|
||||
<description>Baeldung custom PMD rules</description>
|
||||
<rule name="UnitTestMustFollowNamingConventionRule" message="Unit test class names need to end in 'UnitTest', integration tests with 'IntegrationTest', etc " class="org.baeldung.pmd.UnitTestNamingConventionRule">
|
||||
<rule name="UnitTestMustFollowNamingConventionRule"
|
||||
message="Unit test class names need to end in 'UnitTest', integration tests with 'IntegrationTest', etc "
|
||||
class="org.baeldung.pmd.UnitTestNamingConventionRule"
|
||||
language="java">
|
||||
<description>Test does not follow Baeldung naming convention</description>
|
||||
<priority>3</priority>
|
||||
</rule>
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.arrayslicing;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
public class SlicingArrayUnitTest {
|
||||
private static final String[] LANGUAGES = new String[] { "Python", "Java", "Kotlin", "Scala", "Ruby", "Go", "Rust" };
|
||||
private static final String[] JVM_LANGUAGES = new String[] { "Java", "Kotlin", "Scala" };
|
||||
|
||||
@Test
|
||||
void givenAnArray_whenSlicingUsingStream_shouldGetExpectedResult() {
|
||||
String[] result = Arrays.stream(LANGUAGES, 1, 4).toArray(String[]::new);
|
||||
assertArrayEquals(JVM_LANGUAGES, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAnArray_whenSlicingUsingArraysCopyOfRange_shouldGetExpectedResult() {
|
||||
String[] result = Arrays.copyOfRange(LANGUAGES, 1, 4);
|
||||
assertArrayEquals(JVM_LANGUAGES, result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void givenAnArray_whenSlicingUsingSystemArraycopy_shouldGetExpectedResult() {
|
||||
String[] result = new String[3];
|
||||
System.arraycopy(LANGUAGES, 1, result, 0, 3);
|
||||
assertArrayEquals(JVM_LANGUAGES, result);
|
||||
|
||||
String[] result2 = new String[] { "value one", "value two", "value three", "value four", "value five", "value six", "value seven" };
|
||||
System.arraycopy(LANGUAGES, 1, result2, 2, 3);
|
||||
assertArrayEquals(new String[] { "value one", "value two", "Java", "Kotlin", "Scala", "value six", "value seven" }, result2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAnArray_whenSlicingUsingArrayUtils_shouldGetExpectedResult() {
|
||||
String[] result = ArrayUtils.subarray(LANGUAGES, 1, 4);
|
||||
assertArrayEquals(JVM_LANGUAGES, result);
|
||||
}
|
||||
}
|
@ -10,3 +10,4 @@ This module contains articles about Java array fundamentals. They assume no prev
|
||||
- [Removing an Element from an Array in Java](https://www.baeldung.com/java-array-remove-element)
|
||||
- [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element)
|
||||
- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end)
|
||||
- [Initializing a Boolean Array in Java](https://www.baeldung.com/java-initializing-boolean-array)
|
||||
|
@ -10,3 +10,4 @@
|
||||
- [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)
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.baeldung.enumerationiteratordifferences;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class DataUtil {
|
||||
|
||||
private DataUtil() {
|
||||
}
|
||||
|
||||
static List<Person> getPersons() {
|
||||
Person person1 = new Person("amit", "kumar");
|
||||
Person person2 = new Person("yogi", "kuki");
|
||||
Person person3 = new Person("raj", "dosi");
|
||||
Person person4 = new Person("prakash", "kumar");
|
||||
return Arrays.asList(person1, person2, person3, person4);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.enumerationiteratordifferences;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import static com.baeldung.enumerationiteratordifferences.DataUtil.getPersons;
|
||||
|
||||
public class EnumerationExample {
|
||||
public static void main(String[] args) {
|
||||
|
||||
Vector<Person> people = new Vector<>(getPersons());
|
||||
Enumeration<Person> enumeration = people.elements();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
System.out.println("First Name = " + enumeration.nextElement()
|
||||
.getFirstName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.baeldung.enumerationiteratordifferences;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.baeldung.enumerationiteratordifferences.DataUtil.getPersons;
|
||||
|
||||
public class IteratorExample {
|
||||
public static void main(String[] args) {
|
||||
List<Person> persons = getPersons();
|
||||
Iterator<Person> iterator = persons.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
System.out.println("First Name = " + iterator.next()
|
||||
.getFirstName());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.baeldung.enumerationiteratordifferences;
|
||||
|
||||
public class Person {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Person(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
@ -27,15 +27,13 @@ class ListToStringUnitTest {
|
||||
List<String> arraysAsList = Arrays.asList("ONE", "TWO", "THREE");
|
||||
|
||||
StringJoiner stringJoiner = new StringJoiner(",");
|
||||
arraysAsList.stream()
|
||||
.forEach(v -> stringJoiner.add(v));
|
||||
arraysAsList.forEach(stringJoiner::add);
|
||||
String commaSeparatedString = stringJoiner.toString();
|
||||
|
||||
assertThat(commaSeparatedString).isEqualTo("ONE,TWO,THREE");
|
||||
|
||||
StringJoiner stringJoinerWithDelimiterPrefixSuffix = new StringJoiner(",", "[", "]");
|
||||
arraysAsList.stream()
|
||||
.forEach(v -> stringJoinerWithDelimiterPrefixSuffix.add(v));
|
||||
arraysAsList.forEach(stringJoinerWithDelimiterPrefixSuffix::add);
|
||||
String commaSeparatedStringWithDelimiterPrefixSuffix = stringJoinerWithDelimiterPrefixSuffix.toString();
|
||||
|
||||
assertThat(commaSeparatedStringWithDelimiterPrefixSuffix).isEqualTo("[ONE,TWO,THREE]");
|
||||
|
@ -54,11 +54,11 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<streamex.version>0.6.5</streamex.version>
|
||||
<streamex.version>0.8.1</streamex.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
<eclipse-collections.version>8.2.0</eclipse-collections.version>
|
||||
<hppc.version>0.7.2</hppc.version>
|
||||
<fastutil.version>8.1.0</fastutil.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -15,6 +15,11 @@
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.ws.rs</groupId>
|
||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
@ -62,8 +67,8 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.9</maven.compiler.source>
|
||||
<maven.compiler.target>1.9</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.multivaluedmap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
// Unit test for MultivaluedMap.
|
||||
public class MultivaluedMapUnitTest {
|
||||
|
||||
// Testing MultivaluedHashMap.
|
||||
@Test
|
||||
public void givenMultivaluedHashMap_whenEquals_thenTrue() {
|
||||
jakarta.ws.rs.core.MultivaluedMap<String, Integer> mulmap = new jakarta.ws.rs.core.MultivaluedHashMap<>();
|
||||
|
||||
// Mapping keys to values.
|
||||
mulmap.addAll("first", 1, 2, 3);
|
||||
mulmap.add(null, null);
|
||||
|
||||
assertNotNull(mulmap, "The MultivaluedHashMap is null!");
|
||||
assertEquals(1, mulmap.getFirst("first"), "The key isn't mapped to the right values!");
|
||||
assertEquals(null, mulmap.getFirst(null), "MultivaluedHashMap didn't accept null!");
|
||||
}
|
||||
|
||||
// Testing HashMap.
|
||||
@Test
|
||||
public void givenHashMap_whenEquals_thenTrue() {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
|
||||
// Putting key-value pairs into our map.
|
||||
map.put("first", 1);
|
||||
map.put(null, 2);
|
||||
map.put("third", null);
|
||||
|
||||
assertNotNull(map, "The HashMap is null!");
|
||||
assertEquals(1, map.get("first"), "The key isn't mapped to the right value!");
|
||||
assertEquals(2, map.get(null), "HashMap didn't accept null as key!");
|
||||
assertEquals(null, map.get("third"), "HashMap didn't accept null value!");
|
||||
}
|
||||
}
|
4
core-java-modules/core-java-collections-set-2/README.md
Normal file
4
core-java-modules/core-java-collections-set-2/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
## Relevant articles
|
||||
|
||||
- [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)
|
39
core-java-modules/core-java-collections-set-2/pom.xml
Normal file
39
core-java-modules/core-java-collections-set-2/pom.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?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-collections-set-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>core-java-collections-set-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>
|
||||
|
||||
<dependencies>
|
||||
</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}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.treeset.collectintotreeset;
|
||||
|
||||
public class Player implements Comparable<Player> {
|
||||
private String name;
|
||||
private int age;
|
||||
private int numberOfPlayed;
|
||||
private int numberOfWins;
|
||||
|
||||
public Player(String name, int age, int numberOfPlayed, int numberOfWins) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.numberOfPlayed = numberOfPlayed;
|
||||
this.numberOfWins = numberOfWins;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public int getNumberOfPlayed() {
|
||||
return numberOfPlayed;
|
||||
}
|
||||
|
||||
public int getNumberOfWins() {
|
||||
return numberOfWins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Player o) {
|
||||
return Integer.compare(age, o.age);
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package com.baeldung.linkedhashset;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
public class LinkedHashSetUnitTest{
|
||||
|
||||
|
||||
@Test
|
||||
void whenCreatingLinkedHashSet_shouldBeEmpty(){
|
||||
Set<String> linkedHashSet = new LinkedHashSet<>();
|
||||
assertTrue(linkedHashSet.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreatingLinkedHashSetWithInitialCapacity_shouldBeEmpty(){
|
||||
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(20);
|
||||
assertTrue(linkedHashSet.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreatingLinkedHashSetWithExistingCollection_shouldContainAllElementOfCollection(){
|
||||
Collection<String> data = Arrays.asList("first", "second", "third", "fourth", "fifth");
|
||||
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(data);
|
||||
|
||||
assertFalse(linkedHashSet.isEmpty());
|
||||
assertEquals(data.size(), linkedHashSet.size());
|
||||
assertTrue(linkedHashSet.containsAll(data) && data.containsAll(linkedHashSet));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreatingLinkedHashSetWithInitialCapacityAndLoadFactor_shouldBeEmpty(){
|
||||
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(20, 3);
|
||||
assertTrue(linkedHashSet.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAddingElement_shouldAddElement(){
|
||||
Set<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
assertTrue(linkedHashSet.add(0));
|
||||
assertFalse(linkedHashSet.add(0));
|
||||
assertTrue(linkedHashSet.contains(0));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAddingCollection_shouldAddAllContentOfCollection(){
|
||||
Collection<Integer> data = Arrays.asList(1,2,3);
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
|
||||
assertTrue(linkedHashSet.addAll(data));
|
||||
assertTrue(data.containsAll(linkedHashSet) && linkedHashSet.containsAll(data));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAddingCollectionWithDuplicateElements_shouldMaintainUniqueValuesInSet(){
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
linkedHashSet.add(2);
|
||||
Collection<Integer> data = Arrays.asList(1, 1, 2, 3);
|
||||
|
||||
assertTrue(linkedHashSet.addAll(data));
|
||||
assertEquals(3, linkedHashSet.size());
|
||||
assertTrue(data.containsAll(linkedHashSet) && linkedHashSet.containsAll(data));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingWithIterator_assertThatElementIsPresent(){
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
linkedHashSet.add(0);
|
||||
linkedHashSet.add(1);
|
||||
linkedHashSet.add(2);
|
||||
|
||||
Iterator<Integer> iterator = linkedHashSet.iterator();
|
||||
for (int i = 0; i < linkedHashSet.size(); i++) {
|
||||
int nextData = iterator.next();
|
||||
assertEquals(i, nextData);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenIteratingWithSpliterator_assertThatElementIsPresent(){
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
linkedHashSet.add(0);
|
||||
linkedHashSet.add(1);
|
||||
linkedHashSet.add(2);
|
||||
|
||||
Spliterator<Integer> spliterator = linkedHashSet.spliterator();
|
||||
AtomicInteger counter = new AtomicInteger();
|
||||
spliterator.forEachRemaining(data -> {
|
||||
assertEquals(counter.get(), (int)data);
|
||||
counter.getAndIncrement();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenRemovingAnElement_shouldRemoveElement(){
|
||||
Collection<String> data = Arrays.asList("first", "second", "third", "fourth", "fifth");
|
||||
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(data);
|
||||
|
||||
assertTrue(linkedHashSet.remove("second"));
|
||||
assertFalse(linkedHashSet.contains("second"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenRemovingAnElementGreaterThanTwo_shouldRemoveElement(){
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
linkedHashSet.add(0);
|
||||
linkedHashSet.add(1);
|
||||
linkedHashSet.add(2);
|
||||
linkedHashSet.add(3);
|
||||
linkedHashSet.add(4);
|
||||
|
||||
linkedHashSet.removeIf(data -> data > 2);
|
||||
assertFalse(linkedHashSet.contains(3));
|
||||
assertFalse(linkedHashSet.contains(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenRemovingAnElementWithIterator_shouldRemoveElement(){
|
||||
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
|
||||
linkedHashSet.add(0);
|
||||
linkedHashSet.add(1);
|
||||
linkedHashSet.add(2);
|
||||
|
||||
Iterator<Integer> iterator = linkedHashSet.iterator();
|
||||
int elementToRemove = 1;
|
||||
assertTrue(linkedHashSet.contains(elementToRemove));
|
||||
while(iterator.hasNext()){
|
||||
if(elementToRemove == iterator.next()){
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
assertFalse(linkedHashSet.contains(elementToRemove));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.baeldung.treeset.collectintotreeset;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Comparator;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CollectIntoTreeSetUnitTest {
|
||||
Player kai = new Player("Kai", 26, 28, 7);
|
||||
Player eric = new Player("Eric", 28, 30, 11);
|
||||
Player saajan = new Player("Saajan", 30, 100, 66);
|
||||
Player kevin = new Player("Kevin", 24, 50, 49);
|
||||
|
||||
@Test
|
||||
void givenAStream_whenCollectIntoTreeSetWithNaturalOrder_thenGetExpectedResult() {
|
||||
String kotlin = "Kotlin";
|
||||
String java = "Java";
|
||||
String python = "Python";
|
||||
String ruby = "Ruby";
|
||||
TreeSet<String> myTreeSet = Stream.of(ruby, java, kotlin, python)
|
||||
.collect(Collectors.toCollection(TreeSet::new));
|
||||
assertThat(myTreeSet).containsExactly(java, kotlin, python, ruby);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAPlayerStream_whenCollectIntoTreeSet_thenGetExpectedResult() {
|
||||
TreeSet<Player> myTreeSet = Stream.of(saajan, eric, kai, kevin)
|
||||
.collect(Collectors.toCollection(TreeSet::new));
|
||||
assertThat(myTreeSet).containsExactly(kevin, kai, eric, saajan);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAPlayerStream_whenCollectIntoTreeSetWithNoOfWinsComparator_thenGetExpectedResult() {
|
||||
TreeSet<Player> myTreeSet = Stream.of(saajan, eric, kai, kevin)
|
||||
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingInt(Player::getNumberOfWins))));
|
||||
assertThat(myTreeSet).containsExactly(kai, eric, kevin, saajan);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAPlayerStream_whenCollectIntoTreeSetWithWinRateComparator_thenGetExpectedResult() {
|
||||
TreeSet<Player> myTreeSet = Stream.of(saajan, eric, kai, kevin)
|
||||
.collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(player -> BigDecimal.valueOf(player.getNumberOfWins())
|
||||
.divide(BigDecimal.valueOf(player.getNumberOfPlayed()), 2, RoundingMode.HALF_UP)))));
|
||||
assertThat(myTreeSet).containsExactly(kai, eric, saajan, kevin);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.baeldung.donerunnables;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RunnableCompletionCheckerWithCompletableFuture {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RunnableCompletionCheckerWithCompletableFuture.class);
|
||||
private static final int NUMBER_OF_RUNNABLES = 5;
|
||||
private static final int PAUSE_MILLIS = 1000;
|
||||
|
||||
private static Runnable RUNNABLE = () -> {
|
||||
try {
|
||||
LOGGER.info("launching runnable");
|
||||
Thread.sleep(PAUSE_MILLIS);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
List<Runnable> runnables = IntStream.range(0, NUMBER_OF_RUNNABLES)
|
||||
.mapToObj(x -> RUNNABLE)
|
||||
.collect(Collectors.toList());
|
||||
CompletableFuture<?>[] completableFutures = runAsynchronousTasks(runnables);
|
||||
LOGGER.info("Right after the creation of the completable future array, every completable future is done: {}", isEveryCompletableFutureDone(completableFutures));
|
||||
Thread.sleep((NUMBER_OF_RUNNABLES + 1) * PAUSE_MILLIS);
|
||||
LOGGER.info("After {} seconds, every completable future is done: {}", NUMBER_OF_RUNNABLES + 1, isEveryCompletableFutureDone(completableFutures));
|
||||
}
|
||||
|
||||
public static CompletableFuture<?>[] runAsynchronousTasks(List<Runnable> runnables) {
|
||||
return runnables.stream()
|
||||
.map(CompletableFuture::runAsync)
|
||||
.toArray(CompletableFuture<?>[]::new);
|
||||
}
|
||||
|
||||
public static boolean isEveryCompletableFutureDone(CompletableFuture<?>[] completableFutures) {
|
||||
return CompletableFuture.allOf(completableFutures)
|
||||
.isDone();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.baeldung.donerunnables;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RunnableCompletionCheckerWithThreadPoolExecutor {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RunnableCompletionCheckerWithCompletableFuture.class);
|
||||
private static final int NUMBER_OF_RUNNABLES = 5;
|
||||
private static final int PAUSE_MILLIS = 1000;
|
||||
private static final int NUMBER_OF_THREADS = 5;
|
||||
|
||||
private static Runnable RUNNABLE = () -> {
|
||||
try {
|
||||
LOGGER.info("launching runnable");
|
||||
Thread.sleep(PAUSE_MILLIS);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
List<Runnable> runnables = IntStream.range(0, NUMBER_OF_RUNNABLES)
|
||||
.mapToObj(x -> RUNNABLE)
|
||||
.collect(Collectors.toList());
|
||||
ThreadPoolExecutor executor = createThreadPoolExecutor(runnables);
|
||||
executor.shutdown();
|
||||
LOGGER.info("After a timeout of 0 seconds, every Runnable is done: {}", isEveryRunnableDone(executor, 0));
|
||||
Thread.sleep(100);
|
||||
LOGGER.info("After a timeout of 100 milliseconds, every Runnable is done: {}", isEveryRunnableDone(executor, 100));
|
||||
Thread.sleep(2000);
|
||||
LOGGER.info("After a timeout of 2 seconds, every Runnable is done: {}", isEveryRunnableDone(executor, 1500));
|
||||
}
|
||||
|
||||
public static ThreadPoolExecutor createThreadPoolExecutor(List<Runnable> runnables) {
|
||||
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(NUMBER_OF_THREADS);
|
||||
runnables.forEach(executor::execute);
|
||||
return executor;
|
||||
}
|
||||
|
||||
public static boolean isEveryRunnableDone(ThreadPoolExecutor executor, int timeout) throws InterruptedException {
|
||||
return executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
@ -9,3 +9,4 @@
|
||||
- [Differences Between set() and lazySet() in Java Atomic Variables](https://www.baeldung.com/java-atomic-set-vs-lazyset)
|
||||
- [Volatile vs. Atomic Variables in Java](https://www.baeldung.com/java-volatile-vs-atomic)
|
||||
- [What Is “Locked Ownable Synchronizers” in Thread Dump?](https://www.baeldung.com/locked-ownable-synchronizers)
|
||||
- [Understanding java.lang.Thread.State: WAITING (parking)](https://www.baeldung.com/java-lang-thread-state-waiting-parking)
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.baeldung.threadparking;
|
||||
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
final Object syncObj = new Object();
|
||||
Thread t = new Thread(() -> {
|
||||
int acc = 0;
|
||||
for (int i = 1; i <= 100; i++) {
|
||||
acc += i;
|
||||
}
|
||||
System.out.println("Work finished");
|
||||
LockSupport.park(syncObj);
|
||||
System.out.println(acc);
|
||||
});
|
||||
t.setName("PARK-THREAD");
|
||||
t.start();
|
||||
|
||||
// Thread.sleep(1000);
|
||||
LockSupport.unpark(t);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.concurrent.daemon;
|
||||
package com.baeldung.concurrent.startathread;
|
||||
|
||||
public class MultipleThreadsExample {
|
||||
public static void main(String[] args) {
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.concurrent.daemon;
|
||||
package com.baeldung.concurrent.startathread;
|
||||
|
||||
public class NewThread extends Thread {
|
||||
public void run() {
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.concurrent.daemon;
|
||||
package com.baeldung.concurrent.startathread;
|
||||
|
||||
public class SingleThreadExample {
|
||||
public static void main(String[] args) {
|
@ -0,0 +1,39 @@
|
||||
package com.baeldung.concurrent.startathread;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class TimerDemoExample {
|
||||
|
||||
private void scheduleOnce() {
|
||||
TimerTask task = new TimerTask() {
|
||||
public void run() {
|
||||
System.out.println("Task performed on: " + new Date() + "\n" + "Thread's name: " + Thread.currentThread()
|
||||
.getName());
|
||||
}
|
||||
};
|
||||
Timer timer = new Timer("Timer");
|
||||
long delay = 1000L;
|
||||
timer.schedule(task, delay);
|
||||
}
|
||||
|
||||
private void scheduleRecurrently() {
|
||||
TimerTask task = new TimerTask() {
|
||||
public void run() {
|
||||
System.out.println("Recurrent Task performed on: " + new Date() + "\n" + "Thread's name: " + Thread.currentThread()
|
||||
.getName());
|
||||
}
|
||||
};
|
||||
Timer timer = new Timer("Timer");
|
||||
long delay = 1000L;
|
||||
final long period = 1000L;
|
||||
timer.scheduleAtFixedRate(task, delay, period);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TimerDemoExample timerDemoExample = new TimerDemoExample();
|
||||
timerDemoExample.scheduleOnce();
|
||||
timerDemoExample.scheduleRecurrently();
|
||||
}
|
||||
}
|
@ -2,38 +2,40 @@ package com.baeldung.concurrent.waitandnotify;
|
||||
|
||||
public class Data {
|
||||
private String packet;
|
||||
|
||||
|
||||
// True if receiver should wait
|
||||
// False if sender should wait
|
||||
private boolean transfer = true;
|
||||
|
||||
|
||||
public synchronized String receive() {
|
||||
while (transfer) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
System.out.println("Thread Interrupted");
|
||||
Thread.currentThread()
|
||||
.interrupt();
|
||||
System.err.println("Thread Interrupted");
|
||||
}
|
||||
}
|
||||
transfer = true;
|
||||
|
||||
|
||||
String returnPacket = packet;
|
||||
notifyAll();
|
||||
return returnPacket;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void send(String packet) {
|
||||
while (!transfer) {
|
||||
try {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
System.out.println("Thread Interrupted");
|
||||
Thread.currentThread()
|
||||
.interrupt();
|
||||
System.err.println("Thread Interrupted");
|
||||
}
|
||||
}
|
||||
transfer = false;
|
||||
|
||||
|
||||
this.packet = packet;
|
||||
notifyAll();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ public class NetworkDriver {
|
||||
Data data = new Data();
|
||||
Thread sender = new Thread(new Sender(data));
|
||||
Thread receiver = new Thread(new Receiver(data));
|
||||
|
||||
|
||||
sender.start();
|
||||
receiver.start();
|
||||
}
|
||||
|
@ -4,24 +4,24 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Receiver implements Runnable {
|
||||
private Data load;
|
||||
|
||||
|
||||
public Receiver(Data load) {
|
||||
this.load = load;
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
for(String receivedMessage = load.receive();
|
||||
!"End".equals(receivedMessage) ;
|
||||
receivedMessage = load.receive()) {
|
||||
|
||||
for (String receivedMessage = load.receive(); !"End".equals(receivedMessage); receivedMessage = load.receive()) {
|
||||
|
||||
System.out.println(receivedMessage);
|
||||
|
||||
//Thread.sleep() to mimic heavy server-side processing
|
||||
try {
|
||||
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
||||
Thread.sleep(ThreadLocalRandom.current()
|
||||
.nextInt(1000, 5000));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
System.out.println("Thread Interrupted");
|
||||
Thread.currentThread()
|
||||
.interrupt();
|
||||
System.err.println("Thread Interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,29 +4,25 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Sender implements Runnable {
|
||||
private Data data;
|
||||
|
||||
|
||||
public Sender(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
String packets[] = {
|
||||
"First packet",
|
||||
"Second packet",
|
||||
"Third packet",
|
||||
"Fourth packet",
|
||||
"End"
|
||||
};
|
||||
|
||||
String packets[] = { "First packet", "Second packet", "Third packet", "Fourth packet", "End" };
|
||||
|
||||
for (String packet : packets) {
|
||||
data.send(packet);
|
||||
|
||||
|
||||
//Thread.sleep() to mimic heavy server-side processing
|
||||
try {
|
||||
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000));
|
||||
Thread.sleep(ThreadLocalRandom.current()
|
||||
.nextInt(1000, 5000));
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
System.out.println("Thread Interrupted");
|
||||
Thread.currentThread()
|
||||
.interrupt();
|
||||
System.err.println("Thread Interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.thread.join;
|
||||
package com.baeldung.concurrent.threadjoin;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@ -21,49 +21,47 @@ public class ThreadJoinUnitTest {
|
||||
|
||||
SampleThread(int processingCount) {
|
||||
this.processingCount = processingCount;
|
||||
LOGGER.debug("Thread " + this.getName() + " created");
|
||||
LOGGER.info("Thread " + this.getName() + " created");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LOGGER.debug("Thread " + this.getName() + " started");
|
||||
LOGGER.info("Thread " + this.getName() + " started");
|
||||
while (processingCount > 0) {
|
||||
try {
|
||||
Thread.sleep(1000); // Simulate some work being done by thread
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.debug("Thread " + this.getName() + " interrupted.");
|
||||
LOGGER.info("Thread " + this.getName() + " interrupted.");
|
||||
}
|
||||
processingCount--;
|
||||
LOGGER.debug("Inside Thread " + this.getName() + ", processingCount = " + processingCount);
|
||||
LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount);
|
||||
}
|
||||
LOGGER.debug("Thread " + this.getName() + " exiting");
|
||||
LOGGER.info("Thread " + this.getName() + " exiting");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException {
|
||||
Thread t1 = new SampleThread(0);
|
||||
LOGGER.debug("Invoking join.");
|
||||
LOGGER.info("Invoking join");
|
||||
t1.join();
|
||||
LOGGER.debug("Returned from join");
|
||||
LOGGER.debug("Thread state is" + t1.getState());
|
||||
LOGGER.info("Returned from join");
|
||||
LOGGER.info("Thread state is" + t1.getState());
|
||||
assertFalse(t1.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenJoinCalled_waitsTillCompletion()
|
||||
throws InterruptedException {
|
||||
public void givenStartedThread_whenJoinCalled_waitsTillCompletion() throws InterruptedException {
|
||||
Thread t2 = new SampleThread(1);
|
||||
t2.start();
|
||||
LOGGER.debug("Invoking join.");
|
||||
LOGGER.info("Invoking join");
|
||||
t2.join();
|
||||
LOGGER.debug("Returned from join");
|
||||
LOGGER.info("Returned from join");
|
||||
assertFalse(t2.isAlive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout()
|
||||
throws InterruptedException {
|
||||
public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() throws InterruptedException {
|
||||
Thread t3 = new SampleThread(10);
|
||||
t3.start();
|
||||
t3.join(1000);
|
||||
@ -72,19 +70,17 @@ public class ThreadJoinUnitTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void givenThreadTerminated_checkForEffect_notGuaranteed()
|
||||
throws InterruptedException {
|
||||
public void givenThreadTerminated_checkForEffect_notGuaranteed() throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
//not guaranteed to stop even if t4 finishes.
|
||||
//not guaranteed to stop even if t4 finishes.
|
||||
do {
|
||||
|
||||
} while (t4.processingCount > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJoinWithTerminatedThread_checkForEffect_guaranteed()
|
||||
throws InterruptedException {
|
||||
public void givenJoinWithTerminatedThread_checkForEffect_guaranteed() throws InterruptedException {
|
||||
SampleThread t4 = new SampleThread(10);
|
||||
t4.start();
|
||||
do {
|
@ -16,24 +16,24 @@ public class NetworkIntegrationTest {
|
||||
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
||||
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
|
||||
private String expected;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUpStreams() {
|
||||
System.setOut(new PrintStream(outContent));
|
||||
System.setErr(new PrintStream(errContent));
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUpExpectedOutput() {
|
||||
StringWriter expectedStringWriter = new StringWriter();
|
||||
|
||||
|
||||
PrintWriter printWriter = new PrintWriter(expectedStringWriter);
|
||||
printWriter.println("First packet");
|
||||
printWriter.println("Second packet");
|
||||
printWriter.println("Third packet");
|
||||
printWriter.println("Fourth packet");
|
||||
printWriter.close();
|
||||
|
||||
|
||||
expected = expectedStringWriter.toString();
|
||||
}
|
||||
|
||||
@ -42,25 +42,26 @@ public class NetworkIntegrationTest {
|
||||
System.setOut(null);
|
||||
System.setErr(null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenSenderAndReceiver_whenSendingPackets_thenNetworkSynchronized() {
|
||||
Data data = new Data();
|
||||
Thread sender = new Thread(new Sender(data));
|
||||
Thread receiver = new Thread(new Receiver(data));
|
||||
|
||||
|
||||
sender.start();
|
||||
receiver.start();
|
||||
|
||||
|
||||
//wait for sender and receiver to finish before we test against expected
|
||||
try {
|
||||
sender.join();
|
||||
receiver.join();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
System.out.println("Thread Interrupted");
|
||||
Thread.currentThread()
|
||||
.interrupt();
|
||||
System.err.println("Thread Interrupted");
|
||||
}
|
||||
|
||||
|
||||
assertEquals(expected, outContent.toString());
|
||||
}
|
||||
}
|
||||
|
@ -6,3 +6,4 @@
|
||||
- [Formatting Output with printf() in Java](https://www.baeldung.com/java-printstream-printf)
|
||||
- [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java)
|
||||
- [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out)
|
||||
- [How to Log to the Console in Color](https://www.baeldung.com/java-log-console-in-color)
|
||||
|
@ -14,6 +14,14 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.fusesource.jansi</groupId>
|
||||
<artifactId>jansi</artifactId>
|
||||
<version>2.4.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-console</finalName>
|
||||
<resources>
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.color;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ColorLogger {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ColorLogger.class);
|
||||
|
||||
public void logDebug(String logging) {
|
||||
LOGGER.debug("\u001B[34m" + logging + "\u001B[0m");
|
||||
}
|
||||
|
||||
public void logInfo(String logging) {
|
||||
LOGGER.info("\u001B[32m" + logging + "\u001B[0m");
|
||||
}
|
||||
|
||||
public void logError(String logging) {
|
||||
LOGGER.error("\u001B[31m" + logging + "\u001B[0m");
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.baeldung.color;
|
||||
|
||||
import static org.fusesource.jansi.Ansi.ansi;
|
||||
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
|
||||
public class PrintColor {
|
||||
|
||||
public static void main(String[] args) {
|
||||
logColorUsingANSICodes();
|
||||
|
||||
logColorUsingLogger();
|
||||
|
||||
logColorUsingJANSI();
|
||||
}
|
||||
|
||||
private static void logColorUsingANSICodes() {
|
||||
System.out.println("Here's some text");
|
||||
System.out.println("\u001B[31m" + "and now the text is red" + "\u001B[0m");
|
||||
System.out.println("and now back to the default");
|
||||
}
|
||||
|
||||
private static void logColorUsingLogger() {
|
||||
ColorLogger colorLogger = new ColorLogger();
|
||||
colorLogger.logDebug("Some debug logging");
|
||||
colorLogger.logInfo("Some info logging");
|
||||
colorLogger.logError("Some error logging");
|
||||
}
|
||||
|
||||
private static void logColorUsingJANSI() {
|
||||
AnsiConsole.systemInstall();
|
||||
|
||||
System.out.println(ansi().fgRed().a("Some red text").fgYellow().a(" and some yellow text").reset());
|
||||
|
||||
AnsiConsole.systemUninstall();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* More ANSI codes:
|
||||
*
|
||||
* Always conclude your logging with the ANSI reset code: "\u001B[0m"
|
||||
*
|
||||
* In each case, replace # with the corresponding number:
|
||||
*
|
||||
* 0 = black
|
||||
* 1 = red
|
||||
* 2 = green
|
||||
* 3 = yellow
|
||||
* 4 = blue
|
||||
* 5 = purple
|
||||
* 6 = cyan (light blue)
|
||||
* 7 = white
|
||||
*
|
||||
* \u001B[3#m = color font
|
||||
* \u001B[4#m = color background
|
||||
* \u001B[1;3#m = bold font
|
||||
* \u001B[4;3#m = underlined font
|
||||
* \u001B[3;3#m = italics font (not widely supported, works in VS Code)
|
||||
*/
|
@ -0,0 +1,24 @@
|
||||
package com.baeldung.utiltosqldate;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class UtilToSqlDateUtils {
|
||||
|
||||
public static java.util.Date createAmericanDate(String date) throws ParseException {
|
||||
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
isoFormat.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
|
||||
return isoFormat.parse(date);
|
||||
}
|
||||
|
||||
public static void switchTimezone(String timeZone) {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone(timeZone));
|
||||
}
|
||||
|
||||
public static LocalDate getLocalDate(java.util.Date date, String timeZone) {
|
||||
return date.toInstant().atZone(ZoneId.of(timeZone)).toLocalDate();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.utiltosqldate;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
public class UtilToSqlDateUtilsUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenUtilDate_whenCastingToSqlDate_thenThrowException() {
|
||||
Assertions.assertThrows(ClassCastException.class, () -> {
|
||||
java.sql.Date date = (java.sql.Date) new java.util.Date();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUtilDate_whenStandardConversion_thenTimezoneLost() throws ParseException {
|
||||
java.util.Date date = UtilToSqlDateUtils.createAmericanDate("2010-05-23T22:01:02");
|
||||
|
||||
UtilToSqlDateUtils.switchTimezone("America/Los_Angeles");
|
||||
|
||||
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
|
||||
Assertions.assertEquals("2010-05-23", sqlDate.toString());
|
||||
|
||||
UtilToSqlDateUtils.switchTimezone("Rome");
|
||||
sqlDate = new java.sql.Date(date.getTime());
|
||||
Assertions.assertEquals("2010-05-24",sqlDate.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUtilDate_whenConversionToTimestamp_thenKeepTimeInfo() throws ParseException {
|
||||
java.util.Date date = UtilToSqlDateUtils.createAmericanDate("2010-05-23T22:01:02");
|
||||
UtilToSqlDateUtils.switchTimezone("America/Los_Angeles");
|
||||
java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());
|
||||
Assertions.assertEquals("2010-05-23 22:01:02.0",timestamp.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUtilDate_whenUsingJavaTimeConversion_thenTimezoneKept() throws ParseException {
|
||||
java.util.Date date = UtilToSqlDateUtils.createAmericanDate("2010-05-23T22:01:02");
|
||||
|
||||
UtilToSqlDateUtils.switchTimezone("America/Los_Angeles");
|
||||
|
||||
java.time.LocalDate localDate = UtilToSqlDateUtils.getLocalDate(date,"America/Los_Angeles");
|
||||
Assertions.assertEquals(localDate.toString(), "2010-05-23");
|
||||
|
||||
UtilToSqlDateUtils.switchTimezone("Rome");
|
||||
localDate = UtilToSqlDateUtils.getLocalDate(date,"America/Los_Angeles");
|
||||
Assertions.assertEquals(localDate.toString(), "2010-05-23");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.baeldung.instant;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class StringToInstantConverterUnitTest {
|
||||
String stringDate = "09:15:30 PM, Sun 10/09/2022";
|
||||
String pattern = "hh:mm:ss a, EEE M/d/uuuu";
|
||||
|
||||
@Test public void givenStringTimeStamp_whenConvertingWithInstantUsingTimeZone_thenConvertToInstant() {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, Locale.US);
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(stringDate, dateTimeFormatter);
|
||||
ZoneId zoneId = ZoneId.of("America/Chicago");
|
||||
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
|
||||
Instant instant = zonedDateTime.toInstant();
|
||||
assertThat(instant.toString()).isEqualTo("2022-10-10T02:15:30Z");
|
||||
}
|
||||
|
||||
@Test public void givenStringTimeStamp_whenConvertingWithLocalDateTime_thenConvertToInstant() {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, Locale.US);
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(stringDate, dateTimeFormatter);
|
||||
assertThat(localDateTime.toString()).isEqualTo("2022-10-09T21:15:30");
|
||||
}
|
||||
}
|
@ -46,8 +46,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<h2.version>1.4.191</h2.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -12,4 +12,6 @@ This module contains articles about core Java input and output (IO)
|
||||
- [Java Scanner.skip method with examples](https://www.baeldung.com/java-scanner-skip)
|
||||
- [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)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-3)
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.baeldung.mockinginputstream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class GeneratingInputStream extends InputStream {
|
||||
private final int desiredSize;
|
||||
private int actualSize = 0;
|
||||
private final byte[] seed;
|
||||
|
||||
public GeneratingInputStream(int desiredSize, String seed) {
|
||||
this.desiredSize = desiredSize;
|
||||
this.seed = seed.getBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
if (actualSize >= desiredSize) {
|
||||
return -1;
|
||||
}
|
||||
return seed[actualSize++ % seed.length];
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.baeldung.mockinginputstream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
public class MockingInputStreamUnitTest {
|
||||
@Test
|
||||
public void givenSimpleImplementation_shouldProcessInputStream() throws IOException {
|
||||
int byteCount = processInputStream(new InputStream() {
|
||||
private final byte[] msg = "Hello World".getBytes();
|
||||
private int index = 0;
|
||||
@Override
|
||||
public int read() {
|
||||
if (index >= msg.length) {
|
||||
return -1;
|
||||
}
|
||||
return msg[index++];
|
||||
}
|
||||
});
|
||||
assertThat(byteCount).isEqualTo(11);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenByteArrayInputStream_shouldProcessInputStream() throws IOException {
|
||||
String msg = "Hello World";
|
||||
int bytesCount = processInputStream(new ByteArrayInputStream(msg.getBytes()));
|
||||
assertThat(bytesCount).isEqualTo(11);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFileInputStream_shouldProcessInputStream() throws IOException {
|
||||
InputStream inputStream = MockingInputStreamUnitTest.class.getResourceAsStream("/mockinginputstreams/msg.txt");
|
||||
int bytesCount = processInputStream(inputStream);
|
||||
assertThat(bytesCount).isEqualTo(11);
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGeneratingInputStream_shouldProcessInputStream() throws IOException {
|
||||
InputStream inputStream = new GeneratingInputStream(10_000, "Hello World");
|
||||
int bytesCount = processInputStream(inputStream);
|
||||
assertThat(bytesCount).isEqualTo(10_000);
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
int processInputStream(InputStream inputStream) throws IOException {
|
||||
int count = 0;
|
||||
while(inputStream.read() != -1) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
Hello World
|
@ -64,7 +64,6 @@
|
||||
|
||||
<properties>
|
||||
<spring.version>5.0.9.RELEASE</spring.version>
|
||||
<h2.version>1.4.199</h2.version>
|
||||
<apacheds.version>2.0.0.AM26</apacheds.version>
|
||||
<source.version>1.8</source.version>
|
||||
<target.version>1.8</target.version>
|
||||
|
@ -8,3 +8,5 @@ This module contains articles about core features in the Java language
|
||||
- [Advantages and Disadvantages of Using Java Wildcard Imports](https://www.baeldung.com/java-wildcard-imports)
|
||||
- [Toggle a Boolean Variable in Java](https://www.baeldung.com/java-toggle-boolean)
|
||||
- [Handle Classes With the Same Name in Java](https://www.baeldung.com/java-classes-same-name)
|
||||
- [Variable Instantiation on Declaration vs. on Constructor in Java](https://www.baeldung.com/java-variable-instantiation-declaration-vs-constructor)
|
||||
- [Infinity in Java](https://www.baeldung.com/java-infinity)
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.baeldung.infinity;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class DoubleInfinityUnitTest {
|
||||
|
||||
@Test
|
||||
void givenInfinities_whenOperatingWithThem_thenNaNOrInfinity() {
|
||||
Double positiveInfinity = Double.POSITIVE_INFINITY;
|
||||
Double negativeInfinity = Double.NEGATIVE_INFINITY;
|
||||
|
||||
assertEquals(Double.NaN, (positiveInfinity + negativeInfinity));
|
||||
assertEquals(Double.NaN, (positiveInfinity / negativeInfinity));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity - negativeInfinity));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity - positiveInfinity));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (positiveInfinity * negativeInfinity));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInfinityAndPositiveNumber_whenOperatingWithThem_thenInfinity() {
|
||||
Double positiveInfinity = Double.POSITIVE_INFINITY;
|
||||
Double negativeInfinity = Double.NEGATIVE_INFINITY;
|
||||
double positiveNumber = 10.0;
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity + positiveNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity + positiveNumber));
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity - positiveNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity - positiveNumber));
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity * positiveNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity * positiveNumber));
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity / positiveNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity / positiveNumber));
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (positiveNumber - positiveInfinity));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveNumber - negativeInfinity));
|
||||
|
||||
assertEquals(0.0, (positiveNumber / positiveInfinity));
|
||||
assertEquals(-0.0, (positiveNumber / negativeInfinity));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInfinityAndBegativeNumber_whenOperatingWithThem_thenInfinity() {
|
||||
Double positiveInfinity = Double.POSITIVE_INFINITY;
|
||||
Double negativeInfinity = Double.NEGATIVE_INFINITY;
|
||||
double negativeNumber = -10.0;
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity + negativeNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity + negativeNumber));
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (positiveInfinity - negativeNumber));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeInfinity - negativeNumber));
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (positiveInfinity * negativeNumber));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (negativeInfinity * negativeNumber));
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (positiveInfinity / negativeNumber));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (negativeInfinity / negativeNumber));
|
||||
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (negativeNumber - positiveInfinity));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (negativeNumber - negativeInfinity));
|
||||
|
||||
assertEquals(-0.0, (negativeNumber / positiveInfinity));
|
||||
assertEquals(0.0, (negativeNumber / negativeInfinity));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void givenRealNumbers_whenDivisionByZero_thenInfinity() {
|
||||
double d = 1.0;
|
||||
|
||||
assertEquals(Double.POSITIVE_INFINITY, (d / 0.0));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (d / -0.0));
|
||||
assertEquals(Double.NEGATIVE_INFINITY, (-d / 0.0));
|
||||
assertEquals(Double.POSITIVE_INFINITY, (-d / -0.0));
|
||||
}
|
||||
}
|
@ -6,6 +6,6 @@
|
||||
|
||||
- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
|
||||
- [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables)
|
||||
- [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation/)
|
||||
- [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation)
|
||||
- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.math.standarddeviation;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class StandardDeviation {
|
||||
|
||||
public static double calculateStandardDeviation(double[] array) {
|
||||
|
||||
// get the sum of array
|
||||
double sum = 0.0;
|
||||
for (double i : array) {
|
||||
sum += i;
|
||||
}
|
||||
|
||||
// get the mean of array
|
||||
int length = array.length;
|
||||
double mean = sum / length;
|
||||
|
||||
// calculate the standard deviation
|
||||
double standardDeviation = 0.0;
|
||||
for (double num : array) {
|
||||
standardDeviation += Math.pow(num - mean, 2);
|
||||
}
|
||||
|
||||
return Math.sqrt(standardDeviation / length);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
double[] array = {25, 5, 45, 68, 61, 46, 24, 95};
|
||||
System.out.println("List of elements: " + Arrays.toString(array));
|
||||
|
||||
double standardDeviation = calculateStandardDeviation(array);
|
||||
System.out.format("Standard Deviation = %.6f", standardDeviation);
|
||||
}
|
||||
}
|
@ -13,4 +13,6 @@ This module contains articles about networking in Java
|
||||
- [Get the IP Address of the Current Machine Using Java](https://www.baeldung.com/java-get-ip-address)
|
||||
- [Get Domain Name From Given URL in Java](https://www.baeldung.com/java-domain-name-from-url)
|
||||
- [Java HttpClient Timeout](https://www.baeldung.com/java-httpclient-timeout)
|
||||
- [Port Scanning With Java](https://www.baeldung.com/java-port-scanning)
|
||||
- [Validating URL in Java](https://www.baeldung.com/java-validate-url)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-networking-2)
|
||||
|
@ -58,6 +58,12 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
<version>${apache.commons-validator.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -90,6 +96,7 @@
|
||||
<jgonian.commons-ip-math.version>1.32</jgonian.commons-ip-math.version>
|
||||
<googlecode.ipv6.version>0.17</googlecode.ipv6.version>
|
||||
<javax.mail.version>1.6.2</javax.mail.version>
|
||||
<apache.commons-validator.version>1.7</apache.commons-validator.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.urlvalidation;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.validator.routines.UrlValidator;
|
||||
|
||||
public class UrlValidation {
|
||||
public boolean isValidURLJavaNet(String url) throws MalformedURLException, URISyntaxException {
|
||||
try {
|
||||
new URL(url).toURI();
|
||||
return true;
|
||||
} catch (MalformedURLException e) {
|
||||
return false;
|
||||
} catch (URISyntaxException e) {
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean invalidUrlAsValidJavaNet(String url) throws MalformedURLException {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (MalformedURLException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValidURLApache(String url) throws MalformedURLException {
|
||||
UrlValidator validator = new UrlValidator();
|
||||
return validator.isValid(url);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.baeldung.urlvalidation;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.urlvalidation.UrlValidation;
|
||||
|
||||
public class UrlValidateUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenValidStringAsURL_whenUsingJDK_shouldReturnTrue() throws MalformedURLException, URISyntaxException {
|
||||
UrlValidation urlValidator = new UrlValidation();
|
||||
assertTrue(urlValidator.isValidURLJavaNet("http://baeldung.com/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidStringAsURL_whenUsingJDK_shouldReturnFalse() throws MalformedURLException, URISyntaxException {
|
||||
UrlValidation urlValidator = new UrlValidation();
|
||||
assertFalse(urlValidator.isValidURLJavaNet("https://www.baeldung.com/ java-%%$^&& iuyi"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidStringAsURL_whenUsingJDK_shouldReturnTrue() throws MalformedURLException {
|
||||
UrlValidation urlValidator = new UrlValidation();
|
||||
assertTrue(urlValidator.invalidUrlAsValidJavaNet("https://www.baeldung.com/ java-%%$^&& iuyi"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidStringAsURL_whenUsingApache_shouldReturnTrue() throws MalformedURLException {
|
||||
UrlValidation urlValidator = new UrlValidation();
|
||||
assertTrue(urlValidator.isValidURLApache("http://baeldung.com/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidStringAsURL_whenUsingApache_shouldReturnFalse() throws MalformedURLException {
|
||||
UrlValidation urlValidator = new UrlValidation();
|
||||
assertFalse(urlValidator.isValidURLApache("https://www.baeldung.com/ java-%%$^&& iuyi"));
|
||||
}
|
||||
}
|
2
core-java-modules/core-java-networking-4/README.md
Normal file
2
core-java-modules/core-java-networking-4/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
## Relevant Articles:
|
||||
- [Difference Between URI.create() and new URI()](https://www.baeldung.com/java-uri-create-and-new-uri)
|
19
core-java-modules/core-java-networking-4/pom.xml
Normal file
19
core-java-modules/core-java-networking-4/pom.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?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-networking-4</artifactId>
|
||||
<name>core-java-networking-4</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-networking-4</finalName>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.uricreation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class UriCreationUnitTest {
|
||||
@Test
|
||||
void givenValidUriString_whenUsingConstructor_shouldGetExpectedResult() {
|
||||
try {
|
||||
URI myUri = new URI("https://www.baeldung.com/articles");
|
||||
assertNotNull(myUri);
|
||||
} catch (URISyntaxException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInvalidUriString_whenUsingConstructor_shouldGetExpectedResult() {
|
||||
assertThrows(URISyntaxException.class, () -> new URI("I am an invalid URI string."));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenValidUriString_whenUsingCreateMethod_shouldGetExpectedResult() {
|
||||
URI myUri = URI.create("https://www.baeldung.com/articles");
|
||||
assertNotNull(myUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInvalidUriString_whenUsingCreateMethod_shouldGetExpectedResult() {
|
||||
assertThrows(IllegalArgumentException.class, () -> URI.create("I am an invalid URI string."));
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.uniquerng;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class BigUniqueRng implements Iterator<Integer> {
|
||||
|
||||
private Random random = new Random();
|
||||
private Set<Integer> generated = new LinkedHashSet<>();
|
||||
|
||||
public BigUniqueRng(int size, int max) {
|
||||
while (generated.size() < size) {
|
||||
Integer next = random.nextInt(max);
|
||||
generated.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
Iterator<Integer> iterator = generated.iterator();
|
||||
Integer next = iterator.next();
|
||||
iterator.remove();
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !generated.isEmpty();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.baeldung.uniquerng;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class UniqueRng implements Iterator<Integer> {
|
||||
|
||||
private int size;
|
||||
private List<Integer> numbers = new ArrayList<>();
|
||||
|
||||
public UniqueRng(int size, boolean zeroBased) {
|
||||
this.size = size;
|
||||
int start = (zeroBased ? 0 : 1);
|
||||
int limit = (zeroBased ? size - 1 : size);
|
||||
|
||||
for (int i = start; i <= limit; i++) {
|
||||
numbers.add(i);
|
||||
}
|
||||
|
||||
Collections.shuffle(numbers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
|
||||
return numbers.remove(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !numbers.isEmpty();
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.baeldung.uniquerng;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class RngUtilsUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenNUniqueNumRequested_thenNUniqueNumConsumed() {
|
||||
TreeSet<Integer> set = new TreeSet<>();
|
||||
int n = 5;
|
||||
UniqueRng rng = new UniqueRng(n, true);
|
||||
|
||||
while (rng.hasNext()) {
|
||||
set.add(rng.next());
|
||||
}
|
||||
|
||||
assertEquals(n, set.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenYRange_whenNUniqueNumRequested_thenNUniqueNumConsumed() {
|
||||
TreeSet<Integer> set = new TreeSet<>();
|
||||
int n = 5;
|
||||
int y = n * 10;
|
||||
|
||||
BigUniqueRng rng = new BigUniqueRng(n, y);
|
||||
while (rng.hasNext()) {
|
||||
set.add(rng.next());
|
||||
}
|
||||
|
||||
assertEquals(n, set.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntStreamSizeN_whenCollected_thenSetSizeN() {
|
||||
int n = 5;
|
||||
int from = -5;
|
||||
int to = n * 2;
|
||||
|
||||
Random r = new Random();
|
||||
Set<Integer> set = r.ints(from, to)
|
||||
.distinct()
|
||||
.limit(n)
|
||||
.boxed()
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
assertEquals(n, set.size());
|
||||
}
|
||||
}
|
@ -3,3 +3,6 @@
|
||||
|
||||
- [Compare Characters in Java](https://www.baeldung.com/java-compare-characters)
|
||||
- [String Concatenation in Java](https://www.baeldung.com/java-string-concatenation)
|
||||
- [Capitalize the First Letter of a String in Java](https://www.baeldung.com/java-string-uppercase-first-letter)
|
||||
- [Convert String to char in Java](https://www.baeldung.com/java-convert-string-to-char)
|
||||
- [Convert String to String Array](https://www.baeldung.com/java-convert-string-to-string-array)
|
||||
|
@ -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-string-operations-5</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
@ -14,6 +14,13 @@
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${apache.commons.lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@ -30,6 +37,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<apache.commons.lang3.version>3.12.0</apache.commons.lang3.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,45 @@
|
||||
package com.baeldung.capitalizethefirstletter;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class CapitalizeTheFirstLetterUnitTest {
|
||||
private static final String EMPTY_INPUT = "";
|
||||
private static final String EMPTY_EXPECTED = "";
|
||||
private static final String INPUT = "hi there, Nice to Meet You!";
|
||||
private static final String EXPECTED = "Hi there, Nice to Meet You!";
|
||||
|
||||
@Test
|
||||
void givenString_whenCapitalizeUsingSubString_shouldGetExpectedResult() {
|
||||
String output = INPUT.substring(0, 1).toUpperCase() + INPUT.substring(1);
|
||||
assertEquals(EXPECTED, output);
|
||||
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> EMPTY_INPUT.substring(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenCapitalizeUsingRegexReplace_shouldGetExpectedResult() {
|
||||
String output = Pattern.compile("^.").matcher(INPUT).replaceFirst(m -> m.group().toUpperCase());
|
||||
assertEquals(EXPECTED, output);
|
||||
|
||||
String emptyOutput = Pattern.compile("^.").matcher(EMPTY_INPUT).replaceFirst(m -> m.group().toUpperCase());
|
||||
assertEquals(EMPTY_EXPECTED, emptyOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenString_whenCapitalizeUsingApacheCommons_shouldGetExpectedResult() {
|
||||
String output = StringUtils.capitalize(INPUT);
|
||||
assertEquals(EXPECTED, output);
|
||||
|
||||
String emptyOutput = StringUtils.capitalize(EMPTY_INPUT);
|
||||
assertEquals(EMPTY_EXPECTED, emptyOutput);
|
||||
|
||||
String nullOutput = StringUtils.capitalize(null);
|
||||
assertNull(nullOutput);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.baeldung.strtochar;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ConvertStringToCharUnitTest {
|
||||
private static final String STRING_b = "b";
|
||||
private static final String STRING_Baeldung = "Baeldung";
|
||||
|
||||
@Test
|
||||
void givenStringWithSingleChar_whenCallingCharAt_thenGetExpectedResult() {
|
||||
assertEquals('b', STRING_b.charAt(0));
|
||||
assertEquals('l', STRING_Baeldung.charAt(3));
|
||||
assertThrows(StringIndexOutOfBoundsException.class, () -> "".charAt(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenStringWithMultipleChars_whenCallingCharAt_thenGetExpectedResult() {
|
||||
assertArrayEquals(new char[] { 'B', 'a', 'e', 'l', 'd', 'u', 'n', 'g' }, STRING_Baeldung.toCharArray());
|
||||
assertArrayEquals(new char[] {}, "".toCharArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenStringWithMultipleChars_whenCallingGetChars_thenGetExpectedResult() {
|
||||
char[] aeld = new char[4];
|
||||
STRING_Baeldung.getChars(1, 5, aeld, 0);
|
||||
assertArrayEquals(new char[] { 'a', 'e', 'l', 'd' }, aeld);
|
||||
|
||||
char[] anotherArray = new char[] { '#', '#', '#', '#', '#', '#' };
|
||||
STRING_Baeldung.getChars(1, 5, anotherArray, 1);
|
||||
assertArrayEquals(new char[] { '#', 'a', 'e', 'l', 'd', '#' }, anotherArray);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.strtostrarray;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
public class StringToStringArrayUnitTest {
|
||||
private static final String INPUT = "Hi there, nice to meet you!";
|
||||
private static final String FLIGHT_INPUT = "20221018LH720FRAPEK";
|
||||
|
||||
@Test
|
||||
void givenAString_whenConvertToSingletonArray_shouldGetExpectedResult() {
|
||||
String[] myArray = new String[] { INPUT };
|
||||
assertArrayEquals(new String[] { "Hi there, nice to meet you!" }, myArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAString_whenSplitToWordArray_shouldGetExpectedResult() {
|
||||
String[] myArray = INPUT.split("\\W+");
|
||||
assertArrayEquals(new String[] { "Hi", "there", "nice", "to", "meet", "you" }, myArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAString_whenSplitToSentenceArray_shouldGetExpectedResult() {
|
||||
String[] myArray = INPUT.split("[-,.!;?]\\s*");
|
||||
assertArrayEquals(new String[] { "Hi there", "nice to meet you" }, myArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAString_whenSplitToCharArray_shouldGetExpectedResult() {
|
||||
String[] myArray = INPUT.split("");
|
||||
assertArrayEquals(new String[] {
|
||||
"H", "i", " ", "t", "h", "e", "r", "e", ",", " ",
|
||||
"n", "i", "c", "e", " ", "t", "o", " ", "m", "e", "e", "t", " ", "y", "o", "u", "!"
|
||||
}, myArray);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAString_whenSpecialRuleRequired_shouldGetExpectedResult() {
|
||||
String dateStr = FLIGHT_INPUT.substring(0, 8);
|
||||
String flightNo = FLIGHT_INPUT.substring(8, FLIGHT_INPUT.length() - 6);
|
||||
int airportStart = dateStr.length() + flightNo.length();
|
||||
String from = FLIGHT_INPUT.substring(airportStart, airportStart + 3);
|
||||
String to = FLIGHT_INPUT.substring(airportStart + 3);
|
||||
|
||||
String[] myArray = new String[] { dateStr, flightNo, from, to };
|
||||
assertArrayEquals(new String[] { "20221018", "LH720", "FRA", "PEK" }, myArray);
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
<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>
|
||||
<module>core-java-collections-list</module>
|
||||
<module>core-java-collections-list-2</module>
|
||||
<module>core-java-collections-list-3</module>
|
||||
@ -97,6 +98,7 @@
|
||||
<module>core-java-lang-syntax-2</module>
|
||||
<module>core-java-networking</module>
|
||||
<module>core-java-networking-2</module>
|
||||
<module>core-java-networking-4</module>
|
||||
<module>core-java-nio</module>
|
||||
<module>core-java-nio-2</module>
|
||||
<module>core-java-numbers</module>
|
||||
@ -147,4 +149,4 @@
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -5,6 +5,6 @@
|
||||
- [Communication Between Multiple Docker Compose Projects](https://www.baeldung.com/ops/docker-compose-communication)
|
||||
- [Difference Between links and depends_on in Docker Compose](https://www.baeldung.com/ops/docker-compose-links-depends-on)
|
||||
- [Mounting Multiple Volumes on a Docker Container](https://www.baeldung.com/ops/docker-mounting-multiple-volumes)
|
||||
- [Rebuild Docker Container in Docker Compose](https://www.baeldung.com/rebuild-docker-container-compose/)
|
||||
- [Rebuild Docker Container in Docker Compose](https://www.baeldung.com/rebuild-docker-container-compose)
|
||||
- [Assign Static IP to Docker Container and Docker-Compose](https://www.baeldung.com/ops/docker-assign-static-ip-container)
|
||||
|
||||
- [Exclude a Sub-Folder When Adding a Volume to Docker](https://www.baeldung.com/ops/docker-exclude-sub-folder-when-adding-volume)
|
||||
|
@ -0,0 +1,7 @@
|
||||
FROM node:12.18.1
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /app
|
||||
COPY ["package.json", "package-lock.json*", "./"]
|
||||
RUN npm install --production
|
||||
COPY . .
|
||||
CMD [ "node", "server.js" ]
|
@ -0,0 +1,12 @@
|
||||
services:
|
||||
node-app:
|
||||
build: .
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- .:/app
|
||||
- my-vol:/app/node_modules/
|
||||
|
||||
volumes:
|
||||
my-vol:
|
||||
driver: local
|
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ronin-mocks": "^0.1.11",
|
||||
"ronin-server": "^0.1.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
const ronin = require('ronin-server')
|
||||
const mocks = require('ronin-mocks')
|
||||
|
||||
const server = ronin.server()
|
||||
|
||||
server.use('/', mocks.server(server.Router(), false, true))
|
||||
server.start()
|
@ -2,6 +2,6 @@
|
||||
|
||||
- [Pushing a Docker Image to a Private Repository](https://www.baeldung.com/ops/docker-push-image-to-private-repository)
|
||||
- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context)
|
||||
- [Adding a Comment in a Dockerfile](https://www.baeldung.com/ops/docker-dockerfile-comments/)
|
||||
- [Adding a Comment in a Dockerfile](https://www.baeldung.com/ops/docker-dockerfile-comments)
|
||||
- [Updating PATH Environment Variable in Dockerfile](https://www.baeldung.com/ops/dockerfile-path-environment-variable)
|
||||
- [Keep Subdirectory Structure in Dockerfile Copy](https://www.baeldung.com/ops/dockerfile-copy-same-subdirectory-structure)
|
||||
|
@ -1,3 +0,0 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Error Handling in GraphQL With Spring Boot](https://www.baeldung.com/spring-graphql-error-handling)
|
@ -1,80 +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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>graphql-error-handling</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>graphql-error-handling</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.graphql</groupId>
|
||||
<artifactId>graphql-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<!-- Boot version compatible with graphql-spring-boot-starter -->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>2.6.4</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-spring-boot-starter</artifactId>
|
||||
<version>${graphql-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-java-tools</artifactId>
|
||||
<version>${graphql-java-tools.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-spring-boot-starter-test</artifactId>
|
||||
<version>${graphql-spring-boot-starter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<graphql-spring-boot-starter.version>5.0.2</graphql-spring-boot-starter.version>
|
||||
<graphql-java-tools.version>5.2.4</graphql-java-tools.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -1,46 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling;
|
||||
|
||||
import com.baeldung.graphql.error.handling.exception.GraphQLErrorAdapter;
|
||||
import graphql.ExceptionWhileDataFetching;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.servlet.GraphQLErrorHandler;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SpringBootApplication
|
||||
public class GraphQLErrorHandlerApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GraphQLErrorHandlerApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GraphQLErrorHandler errorHandler() {
|
||||
return new GraphQLErrorHandler() {
|
||||
@Override
|
||||
public List<GraphQLError> processErrors(List<GraphQLError> errors) {
|
||||
List<GraphQLError> clientErrors = errors.stream()
|
||||
.filter(this::isClientError)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<GraphQLError> serverErrors = errors.stream()
|
||||
.filter(e -> !isClientError(e))
|
||||
.map(GraphQLErrorAdapter::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<GraphQLError> e = new ArrayList<>();
|
||||
e.addAll(clientErrors);
|
||||
e.addAll(serverErrors);
|
||||
return e;
|
||||
}
|
||||
|
||||
private boolean isClientError(GraphQLError error) {
|
||||
return !(error instanceof ExceptionWhileDataFetching || error instanceof Throwable);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling.exception;
|
||||
|
||||
import graphql.ErrorType;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.language.SourceLocation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AbstractGraphQLException extends RuntimeException implements GraphQLError {
|
||||
private Map<String, Object> parameters = new HashMap();
|
||||
|
||||
public AbstractGraphQLException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AbstractGraphQLException(String message, Map<String, Object> additionParams) {
|
||||
this(message);
|
||||
if (additionParams != null) {
|
||||
parameters = additionParams;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SourceLocation> getLocations() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorType getErrorType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtensions() {
|
||||
return this.parameters;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling.exception;
|
||||
|
||||
import graphql.ErrorType;
|
||||
import graphql.ExceptionWhileDataFetching;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.language.SourceLocation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GraphQLErrorAdapter implements GraphQLError {
|
||||
|
||||
private GraphQLError error;
|
||||
|
||||
public GraphQLErrorAdapter(GraphQLError error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getExtensions() {
|
||||
return error.getExtensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SourceLocation> getLocations() {
|
||||
return error.getLocations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorType getErrorType() {
|
||||
return error.getErrorType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getPath() {
|
||||
return error.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> toSpecification() {
|
||||
return error.toSpecification();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return (error instanceof ExceptionWhileDataFetching) ? ((ExceptionWhileDataFetching) error).getException().getMessage() : error.getMessage();
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling.exception;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class VehicleNotFoundException extends AbstractGraphQLException {
|
||||
|
||||
public VehicleNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public VehicleNotFoundException(String message, Map<String, Object> params) {
|
||||
super(message, params);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling.resolver;
|
||||
|
||||
import com.baeldung.graphql.error.handling.domain.Location;
|
||||
import com.baeldung.graphql.error.handling.domain.Vehicle;
|
||||
import com.baeldung.graphql.error.handling.service.InventoryService;
|
||||
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Mutation implements GraphQLMutationResolver {
|
||||
private InventoryService inventoryService;
|
||||
|
||||
public Mutation(InventoryService inventoryService) {
|
||||
this.inventoryService = inventoryService;
|
||||
}
|
||||
|
||||
public Vehicle addVehicle(String vin, Integer year, String make, String model, String trim, Location location) {
|
||||
return this.inventoryService.addVehicle(vin, year, make, model, trim, location);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling.resolver;
|
||||
|
||||
import com.baeldung.graphql.error.handling.domain.Vehicle;
|
||||
import com.baeldung.graphql.error.handling.service.InventoryService;
|
||||
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class Query implements GraphQLQueryResolver {
|
||||
private final InventoryService inventoryService;
|
||||
|
||||
public Query(InventoryService inventoryService) {
|
||||
this.inventoryService = inventoryService;
|
||||
}
|
||||
|
||||
public List<Vehicle> searchAll() {
|
||||
return this.inventoryService.searchAll();
|
||||
}
|
||||
|
||||
public List<Vehicle> searchByLocation(String zipcode) {
|
||||
return this.inventoryService.searchByLocation(zipcode);
|
||||
}
|
||||
|
||||
public Vehicle searchByVin(String vin) {
|
||||
return this.inventoryService.searchByVin(vin);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
insert into LOCATION values('07092', 'Mountainside', 'NJ');
|
||||
insert into LOCATION values ('94118', 'San Francisco', 'CA');
|
||||
insert into LOCATION values ('10002', 'New York', 'NY');
|
||||
|
||||
insert into VEHICLE (vin, year, make, model, trim, fk_location) values('KM8JN72DX7U587496', 2007, 'Hyundai', 'Tucson', null, '07092');
|
||||
insert into VEHICLE (vin, year, make, model, trim, fk_location) values('JTKKU4B41C1023346', 2012, 'Toyota', 'Scion', 'Xd', '94118');
|
||||
insert into VEHICLE (vin, year, make, model, trim, fk_location) values('1G1JC1444PZ215071', 2000, 'Chevrolet', 'CAVALIER VL', 'RS', '07092');
|
@ -1,55 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling;
|
||||
|
||||
import com.graphql.spring.boot.test.GraphQLResponse;
|
||||
import com.graphql.spring.boot.test.GraphQLTestTemplate;
|
||||
import org.json.JSONException;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.baeldung.graphql.error.handling.TestUtils.readFile;
|
||||
import static java.lang.String.format;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = GraphQLErrorHandlerApplication.class)
|
||||
public class GraphQLErrorHandlerApplicationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private GraphQLTestTemplate graphQLTestTemplate;
|
||||
|
||||
private static final String GRAPHQL_TEST_REQUEST_PATH = "graphql/request/%s.graphql";
|
||||
private static final String GRAPHQL_TEST_RESPONSE_PATH = "graphql/response/%s.json";
|
||||
|
||||
@Test
|
||||
public void whenUnknownOperation_thenRespondWithRequestError() throws IOException, JSONException {
|
||||
String graphqlName = "request_error_unknown_operation";
|
||||
GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName));
|
||||
String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName));
|
||||
|
||||
JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInvalidSyntaxRequest_thenRespondWithRequestError() throws IOException, JSONException {
|
||||
String graphqlName = "request_error_invalid_request_syntax";
|
||||
GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName));
|
||||
String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName));
|
||||
|
||||
JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestAllNonNullField_thenRespondPartialDataWithFieldError() throws IOException, JSONException {
|
||||
String graphqlName = "field_error_request_non_null_fields_partial_response";
|
||||
GraphQLResponse actualResponse = graphQLTestTemplate.postForResource(format(GRAPHQL_TEST_REQUEST_PATH, graphqlName));
|
||||
String expectedResponse = readFile(format(GRAPHQL_TEST_RESPONSE_PATH, graphqlName));
|
||||
|
||||
JSONAssert.assertEquals(expectedResponse, actualResponse.getRawResponse().getBody(), true);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.baeldung.graphql.error.handling;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class TestUtils {
|
||||
public static String readFile(String path) throws IOException {
|
||||
return IOUtils.toString(
|
||||
new ClassPathResource(path).getInputStream(), Charset.defaultCharset()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# trim is non null but one of the record has null value for trim
|
||||
query {
|
||||
searchAll {
|
||||
vin
|
||||
year
|
||||
make
|
||||
model
|
||||
trim
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"data": {
|
||||
"searchAll": [
|
||||
null,
|
||||
{
|
||||
"vin": "JTKKU4B41C1023346",
|
||||
"year": 2012,
|
||||
"make": "Toyota",
|
||||
"model": "Scion",
|
||||
"trim": "Xd"
|
||||
},
|
||||
{
|
||||
"vin": "1G1JC1444PZ215071",
|
||||
"year": 2000,
|
||||
"make": "Chevrolet",
|
||||
"model": "CAVALIER VL",
|
||||
"trim": "RS"
|
||||
}
|
||||
]
|
||||
},
|
||||
"errors": [
|
||||
{
|
||||
"message": "Cannot return null for non-nullable type: 'String' within parent 'Vehicle' (/searchAll[0]/trim)",
|
||||
"path": [
|
||||
"searchAll",
|
||||
0,
|
||||
"trim"
|
||||
],
|
||||
"errorType": "DataFetchingException",
|
||||
"locations": null,
|
||||
"extensions": null
|
||||
}
|
||||
]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"data": null,
|
||||
"errors": [
|
||||
{
|
||||
"message": "Invalid Syntax",
|
||||
"locations": [
|
||||
{
|
||||
"line": 5,
|
||||
"column": 8,
|
||||
"sourceName": null
|
||||
}
|
||||
],
|
||||
"errorType": "InvalidSyntax",
|
||||
"path": null,
|
||||
"extensions": null
|
||||
}
|
||||
]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"data": null,
|
||||
"errors": [
|
||||
{
|
||||
"errorType": "OperationNotSupported",
|
||||
"locations": [
|
||||
{
|
||||
"line": 1,
|
||||
"column": 1,
|
||||
"sourceName": null
|
||||
}
|
||||
],
|
||||
"extensions": null,
|
||||
"message": "Schema is not configured for subscriptions.",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
3
graphql-modules/graphql-spqr-boot-starter/README.md
Normal file
3
graphql-modules/graphql-spqr-boot-starter/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr)
|
42
graphql-modules/graphql-spqr-boot-starter/pom.xml
Normal file
42
graphql-modules/graphql-spqr-boot-starter/pom.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?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>graphql-spqr-boot-starter</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>graphql-spqr-boot-starter</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.graphql</groupId>
|
||||
<artifactId>graphql-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</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>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.leangen.graphql</groupId>
|
||||
<artifactId>graphql-spqr-spring-boot-starter</artifactId>
|
||||
<version>${graphql-spqr-spring-boot-starter-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<graphql-spqr-spring-boot-starter-version>0.0.6</graphql-spqr-spring-boot-starter-version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -4,8 +4,8 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBootApp {
|
||||
public class SpqrBootStarterApp {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootApp.class, args);
|
||||
SpringApplication.run(SpqrBootStarterApp.class, args);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.sprq;
|
||||
package com.baeldung.spqr;
|
||||
|
||||
import java.util.Objects;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user