diff --git a/.gitignore b/.gitignore index 7725bf202e..d22c792f43 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ jmeter/src/main/resources/*-JMeter*.csv jmeter/src/main/resources/*ReportsDashboard*.csv jmeter/src/main/resources/dashboard/*ReportsDashboard*.csv jmeter/src/main/resources/*FileExtractionExample.csv +jmeter/src/main/resources/*_Summary-Report.csv ninja/devDb.mv.db @@ -120,4 +121,7 @@ libraries-2/src/test/resources/crawler4j/** devDb*.db #jaxb -*.xjb \ No newline at end of file +*.xjb + +#neo4j +persistence-modules/neo4j/data/** \ No newline at end of file diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ClientUtil.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ClientUtil.java new file mode 100644 index 0000000000..2f430dbd64 --- /dev/null +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/ClientUtil.java @@ -0,0 +1,18 @@ +package com.baeldung.httpclient.httpclient; + +import java.io.IOException; + +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; + +public final class ClientUtil { + + private ClientUtil(){} + + public static void closeClient(CloseableHttpClient client) throws IOException { + if (client == null) { + return; + } + + client.close(); + } +} diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/HttpClientCookBookLiveTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/HttpClientCookBookLiveTest.java new file mode 100644 index 0000000000..6484b2f7e5 --- /dev/null +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/httpclient/HttpClientCookBookLiveTest.java @@ -0,0 +1,211 @@ +package com.baeldung.httpclient.httpclient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.ConnectionConfig; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHeaders; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.util.Timeout; + +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +class HttpClientCookBookLiveTest { + + private static final String SAMPLE_GET_URL = "http://www.google.com"; + private static final String SAMPLE_POST_URL = "http://www.github.com"; + + private CloseableHttpClient httpClient; + + private CloseableHttpResponse response; + + @BeforeEach + public final void before() { + httpClient = HttpClientBuilder.create().build(); + } + + @AfterEach + public final void after() throws IOException { + ClientUtil.closeClient(httpClient); + } + + @Test + void givenGetRequestExecuted_thenCorrectStatusCode() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + httpClient.execute(httpGet, + response -> { + assertThat(response.getCode()).isEqualTo(200); + return response; + } + ); + } + + @Test + void givenGetRequestExecuted_thenCorrectContentMimeType() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + httpClient.execute(httpGet, + response -> { + final String contentMimeType = ContentType.parse(response.getEntity().getContentType()).getMimeType(); + assertThat(contentMimeType).isEqualTo(ContentType.TEXT_HTML.getMimeType()); + return response; + } + ); + } + + @Test + void givenGetRequestExecuted_thenCorrectResponse() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + httpClient.execute(httpGet, + response -> { + String bodyAsString = EntityUtils.toString(response.getEntity()); + assertThat(bodyAsString, notNullValue()); + return response; + } + ); + } + + @Test + void whenConfigureTimeoutOnRequest_thenCorrectResponse() throws IOException { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(Timeout.ofMilliseconds(2000L)) + .build(); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .build(); + + HttpGet request = new HttpGet(SAMPLE_GET_URL); + request.setConfig(requestConfig); + + httpClient.execute(request, + response -> { + assertThat(response.getCode()).isEqualTo(200); + return response; + } + ); + } + + @Test + void givenLowSocketTimeOut_whenExecutingRequestWithTimeout_thenException() throws IOException { + ConnectionConfig connConfig = ConnectionConfig.custom() + .setConnectTimeout(1000, TimeUnit.MILLISECONDS) + .setSocketTimeout(20, TimeUnit.MILLISECONDS) + .build(); + + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(Timeout.ofMilliseconds(2000L)) + .build(); + + BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager(); + cm.setConnectionConfig(connConfig); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(cm) + .build(); + + HttpGet request = new HttpGet(SAMPLE_GET_URL); + + assertThrows(SocketTimeoutException.class, () -> { + httpClient.execute(request, resp -> resp); + }); + } + + @Test + void whenExecutingPostRequest_thenNoExceptions() throws IOException { + final HttpPost httpPost = new HttpPost(SAMPLE_POST_URL); + httpClient.execute(httpPost, + response -> { + assertThat(response.getCode()).isEqualTo(200); + return response; + } + ); + } + + @Test + void givenParametersAddedToRequest_thenCorrect() throws IOException { + final HttpPost httpPost = new HttpPost(SAMPLE_POST_URL); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("key1", "value1")); + params.add(new BasicNameValuePair("key2", "value2")); + httpPost.setEntity(new UrlEncodedFormEntity(params, Charset.defaultCharset())); + + httpClient.execute(httpPost, response -> { + assertThat(response.getCode()).isEqualTo(200); + return response; + }); + } + + @Test + void givenRedirectsAreDisabled_whenConsumingUrlWhichRedirects_thenNotRedirected() throws IOException { + CloseableHttpClient client = HttpClientBuilder.create() + .disableRedirectHandling() + .build(); + client.execute(new HttpGet("http://t.co/I5YYd9tddw"), response -> { + assertThat(response.getCode()).isEqualTo(301); + return response; + }); + } + + @Test + void givenHeadersAddedToRequest_thenCorrect() throws IOException { + HttpGet request = new HttpGet(SAMPLE_GET_URL); + request.addHeader(HttpHeaders.ACCEPT, "application/xml"); + httpClient.execute(request, + response -> { + assertThat(response.getCode()).isEqualTo(200); + return response; + } + ); + } + + @Test + void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + httpClient.execute(httpGet, + response -> { + Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE); + assertThat(headers, not(emptyArray())); + return response; + } + ); + } + + @Test + void givenAutoClosableClient_thenCorrect() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + httpClient.execute(httpGet, resp -> { + assertThat(resp.getCode()).isEqualTo(200); + return resp; + }); + } + } + +} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java index 123c51bb86..d421de1c7a 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -9,16 +9,12 @@ import java.util.concurrent.Future; import javax.net.ssl.SSLContext; -import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner; -import org.junit.jupiter.api.Test; - import org.apache.hc.client5.http.async.methods.SimpleHttpRequest; import org.apache.hc.client5.http.async.methods.SimpleHttpResponse; import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder; import org.apache.hc.client5.http.auth.AuthScope; import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; import org.apache.hc.client5.http.classic.methods.HttpGet; -import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.cookie.BasicCookieStore; import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; import org.apache.hc.client5.http.impl.async.HttpAsyncClients; @@ -26,9 +22,9 @@ import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager; import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder; +import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner; import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder; -import org.apache.hc.core5.concurrent.FutureCallback; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.nio.ssl.TlsStrategy; @@ -37,6 +33,8 @@ import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.reactor.IOReactorConfig; import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.TrustStrategy; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.junit.jupiter.api.Test; class HttpAsyncClientLiveTest extends GetRequestMockServer { @@ -56,12 +54,10 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { @Test void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException { - final HttpHost target = new HttpHost(HOST_WITH_COOKIE); - final SimpleHttpRequest request = SimpleRequestBuilder.get() - .setHttpHost(target) + final SimpleHttpRequest request = SimpleRequestBuilder.get(HOST_WITH_COOKIE) + .build(); + final CloseableHttpAsyncClient client = HttpAsyncClients.custom() .build(); - - final CloseableHttpAsyncClient client = HttpAsyncClients.custom().build(); client.start(); @@ -126,6 +122,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { .build(); final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create() + .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .setSslContext(sslContext) .build(); diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java new file mode 100644 index 0000000000..ce8a869e97 --- /dev/null +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java @@ -0,0 +1,20 @@ +package com.baeldung.httpclient; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.impl.client.CloseableHttpClient; + +public final class ClientUtil { + + private ClientUtil(){} + + public static void closeClient(CloseableHttpClient client) throws IOException { + if (client == null) { + return; + } + + client.close(); + } +} diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java new file mode 100644 index 0000000000..8b83419ba1 --- /dev/null +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java @@ -0,0 +1,184 @@ +package com.baeldung.httpclient; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.not; + +import java.io.IOException; +import java.io.InputStream; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.Consts; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHeaders; +import org.apache.http.NameValuePair; + +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +class HttpClientCookBookV4LiveTest { + + private static final String SAMPLE_GET_URL = "http://www.google.com"; + private static final String SAMPLE_POST_URL = "http://www.github.com"; + + private CloseableHttpClient client; + + private CloseableHttpResponse response; + + @BeforeEach + public final void before() { + client = HttpClientBuilder.create().build(); + } + + @AfterEach + public final void after() throws IllegalStateException, IOException { + ResponseUtil.closeResponse(response); + ClientUtil.closeClient(client); + } + + @Test + void givenGetRequestExecuted_thenCorrectStatusCode() throws IOException { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + response = client.execute(httpGet); + assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + } + + @Test + void givenGetRequestExecuted_thenCorrectContentMimeType() throws IOException { + CloseableHttpResponse response = client.execute(new HttpGet(SAMPLE_GET_URL)); + String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType(); + assertThat(contentMimeType, equalTo(ContentType.TEXT_HTML.getMimeType())); + } + + @Test + void givenGetRequestExecuted_thenCorrectResponse() throws IOException { + CloseableHttpResponse response = client.execute(new HttpGet(SAMPLE_GET_URL)); + String bodyAsString = EntityUtils.toString(response.getEntity()); + assertThat(bodyAsString, notNullValue()); + } + + @Test + void givenLowSocketTimeOut_whenExecutingRequestWithTimeout_thenException() throws IOException { + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(1000) + .setConnectTimeout(1000) + .setSocketTimeout(20) + .build(); + HttpGet request = new HttpGet(SAMPLE_POST_URL); + request.setConfig(requestConfig); + + assertThrows(SocketTimeoutException.class, () -> { + response = client.execute(request); + }); + } + + @Test + void givenLowSocketTimeOut_whenSettingTimeoutOnTheClient_thenException(){ + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(1000) + .setConnectTimeout(1000) + .setSocketTimeout(20).build(); + HttpClientBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig); + + client = builder.build(); + HttpGet request = new HttpGet(SAMPLE_GET_URL); + + assertThrows(SocketTimeoutException.class, () -> { + response = client.execute(request); + }); + } + + @Test + void whenExecutingPostRequest_thenNoExceptions() throws IOException { + response = client.execute(new HttpPost(SAMPLE_POST_URL)); + assertThat(response.getStatusLine().getStatusCode(), equalTo(301)); + } + + @Test + void givenParametersAddedToRequest_thenCorrect() throws IOException { + final HttpPost httpPost = new HttpPost(SAMPLE_POST_URL); + final List params = new ArrayList(); + params.add(new BasicNameValuePair("key1", "value1")); + params.add(new BasicNameValuePair("key2", "value2")); + httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8)); + + response = client.execute(new HttpPost(SAMPLE_POST_URL)); + assertThat(response.getStatusLine().getStatusCode(), equalTo(301)); + } + + @Test + void givenRedirectsAreDisabled_whenConsumingUrlWhichRedirects_thenNotRedirected() throws IOException { + CloseableHttpClient client = HttpClientBuilder.create() + .disableRedirectHandling() + .build(); + CloseableHttpResponse response = client.execute(new HttpGet("http://t.co/I5YYd9tddw")); + assertThat(response.getStatusLine().getStatusCode(), equalTo(301)); + } + + @Test + void givenHeadersAddedToRequest_thenCorrect() throws IOException { + HttpGet request = new HttpGet(SAMPLE_GET_URL); + request.addHeader(HttpHeaders.ACCEPT, "application/xml"); + response = client.execute(request); + assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + } + + @Test + void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws IOException { + CloseableHttpResponse response = client.execute(new HttpGet(SAMPLE_GET_URL)); + Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE); + assertThat(headers, not(emptyArray())); + } + + @Test + void givenStreamIsClosed_thenCloseResponse() throws IOException { + response = client.execute(new HttpGet(SAMPLE_GET_URL)); + try { + HttpEntity entity = response.getEntity(); + if (entity != null) { + InputStream instream = entity.getContent(); + instream.close(); + } + } finally { + response.close(); + } + } + + @Test + void givenAutoClosableClient_thenCorrect() throws IOException { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(SAMPLE_GET_URL); + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + // handle response; + HttpEntity entity = response.getEntity(); + if (entity != null) { + try (InputStream instream = entity.getContent()) { + // Process the input stream if needed + } + } + assertThat(response.getStatusLine().getStatusCode(), equalTo(200)); + } + } + } + +} diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index 9a5f6e15ae..81239d4a7b 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -11,3 +11,4 @@ You can build the project from the command line using: *mvn clean install*, or i - [Get Last N Messages in Apache Kafka Topic](https://www.baeldung.com/java-apache-kafka-get-last-n-messages) - [Is a Key Required as Part of Sending Messages to Kafka?](https://www.baeldung.com/java-kafka-message-key) - [Read Data From the Beginning Using Kafka Consumer API](https://www.baeldung.com/java-kafka-consumer-api-read) +- [Get Partition Count for a Topic in Kafka](https://www.baeldung.com/java-kafka-partition-count-topic) diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessagesLiveTest.java similarity index 99% rename from apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java rename to apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessagesLiveTest.java index 94f5907525..b92f65ca5a 100644 --- a/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessages.java +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafaConsumeLastNMessagesLiveTest.java @@ -28,7 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers -public class KafaConsumeLastNMessages { +public class KafaConsumeLastNMessagesLiveTest { private static String TOPIC1 = "baeldung-github"; private static String TOPIC2 = "baeldung-blog"; diff --git a/apache-kafka-2/src/test/java/com/baeldung/kafka/KafkaCountPartitionsLiveTest.java b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafkaCountPartitionsLiveTest.java new file mode 100644 index 0000000000..49950f67b1 --- /dev/null +++ b/apache-kafka-2/src/test/java/com/baeldung/kafka/KafkaCountPartitionsLiveTest.java @@ -0,0 +1,83 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.admin.AdminClient; +import org.apache.kafka.clients.admin.DescribeTopicsResult; +import org.apache.kafka.clients.admin.TopicDescription; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.KafkaFuture; +import org.apache.kafka.common.PartitionInfo; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.ExecutionException; + +@Testcontainers +public class KafkaCountPartitionsLiveTest { + @Container + private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest")); + private final static String TOPIC = "baeldung-kafka-github"; + private final static Integer PARTITION_NUMBER = 3; + private static KafkaProducer producer; + + @BeforeAll + static void setup() throws IOException, InterruptedException { + KAFKA_CONTAINER.addExposedPort(9092); + + KAFKA_CONTAINER.execInContainer( + "/bin/sh", + "-c", + "/usr/bin/kafka-topics " + + "--bootstrap-server localhost:9092 " + + "--create " + + "--replication-factor 1 " + + "--partitions " + PARTITION_NUMBER + " " + + "--topic " + TOPIC + ); + + Properties producerProperties = new Properties(); + producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers()); + producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + + producer = new KafkaProducer<>(producerProperties); + } + + @AfterAll + static void destroy() { + KAFKA_CONTAINER.stop(); + } + + @Test + void testPartitionsForTopic_isEqualToActualNumberAssignedDuringCreation() { + List info = producer.partitionsFor(TOPIC); + Assertions.assertEquals(PARTITION_NUMBER, info.size()); + } + + @Test + void testTopicPartitionDescription_isEqualToActualNumberAssignedDuringCreation() { + Properties props = new Properties(); + props.put("bootstrap.servers", KAFKA_CONTAINER.getBootstrapServers()); + props.put("client.id","java-admin-client"); + props.put("request.timeout.ms", 3000); + props.put("connections.max.idle.ms", 5000); + try(AdminClient client = AdminClient.create(props)){ + DescribeTopicsResult describeTopicsResult = client.describeTopics(Collections.singletonList(TOPIC)); + Map> values = describeTopicsResult.values(); + KafkaFuture topicDescription = values.get(TOPIC); + Assertions.assertEquals(PARTITION_NUMBER, topicDescription.get().partitions().size()); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/aws-modules/aws-s3-v2/README.md b/aws-modules/aws-s3-v2/README.md new file mode 100644 index 0000000000..4ec342894e --- /dev/null +++ b/aws-modules/aws-s3-v2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) diff --git a/aws-modules/aws-s3-v2/pom.xml b/aws-modules/aws-s3-v2/pom.xml new file mode 100644 index 0000000000..888d98e654 --- /dev/null +++ b/aws-modules/aws-s3-v2/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + com.baeldung.s3 + aws-s3-v2 + 1.0-SNAPSHOT + aws-s3-v2 + jar + + + com.baeldung + aws-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + 2.20.52 + 3.6.1 + + + + + software.amazon.awssdk + s3 + ${aws.java.sdk.version} + + + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + false + + + + package + + shade + + + + + + + diff --git a/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/File.java b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/File.java new file mode 100644 index 0000000000..f9fe7f6fb3 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/File.java @@ -0,0 +1,21 @@ +package com.baeldung.s3.listobjects; + +import java.nio.ByteBuffer; + +public class File { + private String name; + private ByteBuffer content; + + public File(String name, ByteBuffer content) { + this.name = name; + this.content = content; + } + + public String getName() { + return name; + } + + public ByteBuffer getContent() { + return content; + } +} diff --git a/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/FileGenerator.java b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/FileGenerator.java new file mode 100644 index 0000000000..7c640591d7 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/FileGenerator.java @@ -0,0 +1,27 @@ +package com.baeldung.s3.listobjects; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class FileGenerator { + + public static List generateFiles(int fileCount, int fileSize) { + List files = new ArrayList<>(); + for (int i = 0; i < fileCount; i++) { + String fileName = "file_" + i + ".txt"; + ByteBuffer fileContent = generateRandomBytes(fileSize); + files.add(new File(fileName, fileContent)); + } + return files; + } + + private static ByteBuffer generateRandomBytes(int size) { + byte[] array = new byte[size]; + new Random().nextBytes(array); + return ByteBuffer.wrap(array); + } + + +} diff --git a/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/Main.java b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/Main.java new file mode 100644 index 0000000000..7b7c95a0d0 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/Main.java @@ -0,0 +1,22 @@ +package com.baeldung.s3.listobjects; + +import software.amazon.awssdk.regions.Region; + +public class Main { + + private static String AWS_BUCKET = "baeldung-tutorial-s3"; + public static Region AWS_REGION = Region.EU_CENTRAL_1; + + public static void main(String[] args) { + S3Service s3Service = new S3Service(AWS_REGION); + + s3Service.putObject(AWS_BUCKET, FileGenerator.generateFiles(1000, 1)); + s3Service.listBuckets(); + s3Service.listObjectsInBucket(AWS_BUCKET); + s3Service.listAllObjectsInBucket(AWS_BUCKET); + s3Service.listAllObjectsInBucketPaginated(AWS_BUCKET, 500); + s3Service.listAllObjectsInBucketPaginatedWithPrefix(AWS_BUCKET, 500, "backup/"); + + s3Service.cleanup(); + } +} diff --git a/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/S3Service.java b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/S3Service.java new file mode 100644 index 0000000000..132123f214 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/main/java/com/baeldung/s3/listobjects/S3Service.java @@ -0,0 +1,129 @@ +package com.baeldung.s3.listobjects; + +import java.util.List; + +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.*; +import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable; + +class S3Service { + + private S3Client s3Client; + + public S3Service(Region awsRegion) { + init(awsRegion); + } + + public S3Service(S3Client s3Client) { + this.s3Client = s3Client; + } + + public void init(Region awsRegion) { + this.s3Client = S3Client.builder() + .region(awsRegion) + .credentialsProvider(ProfileCredentialsProvider.create("default")) + .build(); + } + + public void listObjectsInBucket(String bucketName) { + ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() + .bucket(bucketName) + .build(); + ListObjectsV2Response listObjectsV2Response = s3Client.listObjectsV2(listObjectsV2Request); + + List contents = listObjectsV2Response.contents(); + + System.out.println("Number of objects in the bucket: " + contents.stream().count()); + contents.stream().forEach(System.out::println); + } + + public void listAllObjectsInBucket(String bucketName) { + String nextContinuationToken = null; + long totalObjects = 0; + + do { + ListObjectsV2Request.Builder requestBuilder = ListObjectsV2Request.builder() + .bucket(bucketName) + .continuationToken(nextContinuationToken); + + ListObjectsV2Response response = s3Client.listObjectsV2(requestBuilder.build()); + nextContinuationToken = response.nextContinuationToken(); + + totalObjects += response.contents().stream() + .peek(System.out::println) + .reduce(0, (subtotal, element) -> subtotal + 1, Integer::sum); + } while (nextContinuationToken != null); + System.out.println("Number of objects in the bucket: " + totalObjects); + } + + public void listAllObjectsInBucketPaginated(String bucketName, int pageSize) { + ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() + .bucket(bucketName) + .maxKeys(pageSize) // Set the maxKeys parameter to control the page size + .build(); + + ListObjectsV2Iterable listObjectsV2Iterable = s3Client.listObjectsV2Paginator(listObjectsV2Request); + long totalObjects = 0; + + for (ListObjectsV2Response page : listObjectsV2Iterable) { + long retrievedPageSize = page.contents().stream() + .peek(System.out::println) + .reduce(0, (subtotal, element) -> subtotal + 1, Integer::sum); + totalObjects += retrievedPageSize; + System.out.println("Page size: " + retrievedPageSize); + } + System.out.println("Total objects in the bucket: " + totalObjects); + } + + public void listAllObjectsInBucketPaginatedWithPrefix(String bucketName, int pageSize, String prefix) { + ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() + .bucket(bucketName) + .maxKeys(pageSize) // Set the maxKeys parameter to control the page size + .prefix(prefix) + .build(); + + ListObjectsV2Iterable listObjectsV2Iterable = s3Client.listObjectsV2Paginator(listObjectsV2Request); + long totalObjects = 0; + + for (ListObjectsV2Response page : listObjectsV2Iterable) { + long retrievedPageSize = page.contents().stream() + .peek(System.out::println) + .reduce(0, (subtotal, element) -> subtotal + 1, Integer::sum); + totalObjects += retrievedPageSize; + System.out.println("Page size: " + retrievedPageSize); + } + System.out.println("Total objects in the bucket: " + totalObjects); + } + + public void listBuckets() { + // List all buckets + ListBucketsResponse listBucketsResponse = s3Client.listBuckets(); + + // Display the bucket names + List buckets = listBucketsResponse.buckets(); + System.out.println("Buckets:"); + for (Bucket bucket : buckets) { + System.out.println(bucket.name()); + } + } + + public void putObject(String bucketName, List files) { + try { + files.stream().forEach(file -> { + s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(file.getName()).build(), + RequestBody.fromByteBuffer(file.getContent())); + System.out.println("Uploaded file: " + file.getName()); + }); + } catch (S3Exception e) { + System.err.println("Upload failed"); + e.printStackTrace(); + } + } + + public void cleanup() { + this.s3Client.close(); + } +} \ No newline at end of file diff --git a/aws-modules/aws-s3-v2/src/main/resources/logback.xml b/aws-modules/aws-s3-v2/src/main/resources/logback.xml new file mode 100644 index 0000000000..91d3d0cfa6 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/aws-modules/aws-s3-v2/src/test/java/com/baeldung/s3/listobjects/S3ServiceLiveTest.java b/aws-modules/aws-s3-v2/src/test/java/com/baeldung/s3/listobjects/S3ServiceLiveTest.java new file mode 100644 index 0000000000..40b30f8669 --- /dev/null +++ b/aws-modules/aws-s3-v2/src/test/java/com/baeldung/s3/listobjects/S3ServiceLiveTest.java @@ -0,0 +1,109 @@ +package com.baeldung.s3.listobjects; + +import com.baeldung.s3.listobjects.S3Service; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.ListBucketsResponse; +import software.amazon.awssdk.services.s3.model.ListObjectsV2Request; +import software.amazon.awssdk.services.s3.model.ListObjectsV2Response; +import software.amazon.awssdk.services.s3.model.S3Object; +import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable; + +import java.util.Arrays; +import java.util.Collections; + +import static org.mockito.Mockito.when; + +class S3ServiceLiveTest { + + @Mock + private S3Client s3Client; + + private S3Service s3Service; + + private String AWS_BUCKET = "baeldung-tutorial-s3"; + + @BeforeEach + public void setup() { + MockitoAnnotations.openMocks(this); + s3Service = new S3Service(s3Client); + } + + @AfterEach + public void cleanup() { + s3Service.cleanup(); + Mockito.verify(s3Client).close(); + } + + @Test + public void givenBucketName_whenListObjectsInBucket_thenReturnList() { + ListObjectsV2Request request = ListObjectsV2Request.builder().bucket(AWS_BUCKET).build(); + ListObjectsV2Response response = ListObjectsV2Response.builder().contents(Collections.emptyList()).build(); + + when(s3Client.listObjectsV2(request)).thenReturn(response); + + s3Service.listObjectsInBucket(AWS_BUCKET); + Mockito.verify(s3Client).listObjectsV2(request); + } + + @Test + public void givenBucketName_whenListAllObjectsInBucket_thenReturnList() { + ListObjectsV2Request request = ListObjectsV2Request.builder().bucket(AWS_BUCKET).build(); + ListObjectsV2Response response = ListObjectsV2Response.builder().contents(Collections.emptyList()).build(); + + when(s3Client.listObjectsV2(request)).thenReturn(response); + + s3Service.listAllObjectsInBucket(AWS_BUCKET); + Mockito.verify(s3Client).listObjectsV2(request); + } + + @Test + public void givenBucketNameAndPageSize_whenListAllObjectsInBucketPaginated_thenReturnPaginatedList() { + int pageSize = 10; + ListObjectsV2Request request = ListObjectsV2Request.builder().bucket(AWS_BUCKET).maxKeys(pageSize).build(); + + ListObjectsV2Iterable mockIterable = Mockito.mock(ListObjectsV2Iterable.class); + + S3Object s3Object1 = S3Object.builder().key("object1").build(); + S3Object s3Object2 = S3Object.builder().key("object2").build(); + ListObjectsV2Response response = ListObjectsV2Response.builder().contents(s3Object1, s3Object2).build(); + + when(s3Client.listObjectsV2Paginator(request)).thenReturn(mockIterable); + when(mockIterable.iterator()).thenReturn(Arrays.asList(response).iterator()); + + s3Service.listAllObjectsInBucketPaginated(AWS_BUCKET, pageSize); + Mockito.verify(s3Client).listObjectsV2Paginator(request); + } + + @Test + public void givenBucketNamePageSizeAndPrefix_whenListAllObjectsInBucketPaginatedWithPrefix_thenReturnPaginatedList() { + int pageSize = 1; + String prefix = "folder/"; + ListObjectsV2Request request = ListObjectsV2Request.builder().bucket(AWS_BUCKET).maxKeys(pageSize).prefix(prefix).build(); + + ListObjectsV2Iterable mockIterable = Mockito.mock(ListObjectsV2Iterable.class); + + S3Object s3Object1 = S3Object.builder().key("folder/object1").build(); + S3Object s3Object2 = S3Object.builder().key("folder/object2").build(); + ListObjectsV2Response response = ListObjectsV2Response.builder().contents(s3Object1, s3Object2).build(); + + when(s3Client.listObjectsV2Paginator(request)).thenReturn(mockIterable); + when(mockIterable.iterator()).thenReturn(Arrays.asList(response).iterator()); + + s3Service.listAllObjectsInBucketPaginatedWithPrefix(AWS_BUCKET, pageSize, prefix); + Mockito.verify(s3Client).listObjectsV2Paginator(request); + } + + @Test + public void whenListBuckets_thenReturnBucketList() { + when(s3Client.listBuckets()).thenReturn(ListBucketsResponse.builder().buckets(Collections.emptyList()).build()); + + s3Service.listBuckets(); + Mockito.verify(s3Client).listBuckets(); + } +} diff --git a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java index 792e41a188..64ed043f98 100644 --- a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java +++ b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/AWSS3Service.java @@ -1,6 +1,7 @@ package com.baeldung.s3; import java.io.File; +import java.net.URL; import java.util.List; import com.amazonaws.services.s3.AmazonS3; @@ -49,6 +50,11 @@ public class AWSS3Service { public PutObjectResult putObject(String bucketName, String key, File file) { return s3client.putObject(bucketName, key, file); } + //uploading object and getting url + public URL getObjectURL(String bucketName, String key, File file) { + s3client.putObject(bucketName, key, file); + return s3client.getUrl(bucketName, key); + } //listing objects public ObjectListing listObjects(String bucketName) { diff --git a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java index fdfb909f73..39a9b0050f 100644 --- a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java +++ b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3Application.java @@ -66,6 +66,9 @@ public class S3Application { new File("/Users/user/Document/hello.txt") ); + //uploading object and getting url + awsService.getObjectURL(bucketName, "Document/hello.txt", new File("/Users/user/Document/hello.txt")); + //listing objects ObjectListing objectListing = awsService.listObjects(bucketName); for(S3ObjectSummary os : objectListing.getObjectSummaries()) { diff --git a/aws-modules/pom.xml b/aws-modules/pom.xml index 02473815b5..77872e3f8f 100644 --- a/aws-modules/pom.xml +++ b/aws-modules/pom.xml @@ -19,6 +19,7 @@ aws-miscellaneous aws-reactive aws-s3 + aws-s3-v2 diff --git a/core-java-modules/core-java-19/README.md b/core-java-modules/core-java-19/README.md index 68244d9f91..89ec729ca6 100644 --- a/core-java-modules/core-java-19/README.md +++ b/core-java-modules/core-java-19/README.md @@ -2,3 +2,4 @@ - [Record Patterns in Java 19](https://www.baeldung.com/java-19-record-patterns) - [Structured Concurrency in Java 19](https://www.baeldung.com/java-structured-concurrency) - [Possible Root Causes for High CPU Usage in Java](https://www.baeldung.com/java-high-cpu-usage-causes) +- [The Vector API in Java 19](https://www.baeldung.com/java-vector-api) diff --git a/core-java-modules/core-java-19/pom.xml b/core-java-modules/core-java-19/pom.xml index 930b37391c..11ae8cc224 100644 --- a/core-java-modules/core-java-19/pom.xml +++ b/core-java-modules/core-java-19/pom.xml @@ -21,6 +21,7 @@ 19 19 --enable-preview + --add-modules=jdk.incubator.vector diff --git a/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java b/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java new file mode 100644 index 0000000000..eda36dbfde --- /dev/null +++ b/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java @@ -0,0 +1,100 @@ +package com.baeldung.vectors; + +import jdk.incubator.vector.FloatVector; +import jdk.incubator.vector.IntVector; +import jdk.incubator.vector.VectorOperators; +import jdk.incubator.vector.VectorSpecies; + +/** + * This class contains examples of the Vector API in Java, more specifically the fourth incubator to the Vector API. + * There are scalar and vector methods written here and the method names will specify the type. + * Note that, the code is written without any benchmarking done and without any assumption of it being run on + * a SIMD processor, or any specific compiler. + */ +public class VectorAPIExamples { + + static final VectorSpecies SPECIES = IntVector.SPECIES_PREFERRED; + static final VectorSpecies PREFERRED_SPECIES = FloatVector.SPECIES_PREFERRED; + + public int[] addTwoScalarArrays(int[] arr1, int[] arr2) { + int[] result = new int[arr1.length]; + for (int i = 0; i < arr1.length; i++) { + result[i] = arr1[i] + arr2[i]; + } + return result; + } + + public int[] addTwoVectorArrays(int[] arr1, int[] arr2) { + var v1 = IntVector.fromArray(SPECIES, arr1, 0); + var v2 = IntVector.fromArray(SPECIES, arr2, 0); + var result = v1.add(v2); + return result.toArray(); + } + + public int[] addTwoVectorsWIthHigherShape(int[] arr1, int[] arr2) { + int[] finalResult = new int[arr1.length]; + for (int i = 0; i < arr1.length; i += SPECIES.length()) { + var v1 = IntVector.fromArray(SPECIES, arr1, i); + var v2 = IntVector.fromArray(SPECIES, arr2, i); + var result = v1.add(v2); + result.intoArray(finalResult, i); + } + return finalResult; + } + + public int[] addTwoVectorsWithMasks(int[] arr1, int[] arr2) { + int[] finalResult = new int[arr1.length]; + int i = 0; + for (; i < SPECIES.loopBound(arr1.length); i += SPECIES.length()) { + var mask = SPECIES.indexInRange(i, arr1.length); + var v1 = IntVector.fromArray(SPECIES, arr1, i, mask); + var v2 = IntVector.fromArray(SPECIES, arr2, i, mask); + var result = v1.add(v2, mask); + result.intoArray(finalResult, i, mask); + } + + // tail cleanup loop + for (; i < arr1.length; i++) { + finalResult[i] = arr1[i] + arr2[i]; + } + return finalResult; + } + + public float[] scalarNormOfTwoArrays(float[] arr1, float[] arr2) { + float[] finalResult = new float[arr1.length]; + for (int i = 0; i < arr1.length; i++) { + finalResult[i] = (arr1[i] * arr1[i] + arr2[i] * arr2[i]) * -1.0f; + } + return finalResult; + } + + public float[] vectorNormalForm(float[] arr1, float[] arr2) { + float[] finalResult = new float[arr1.length]; + int i = 0; + int upperBound = SPECIES.loopBound(arr1.length); + for (; i < upperBound; i += SPECIES.length()) { + var va = FloatVector.fromArray(PREFERRED_SPECIES, arr1, i); + var vb = FloatVector.fromArray(PREFERRED_SPECIES, arr2, i); + var vc = va.mul(va) + .add(vb.mul(vb)) + .neg(); + vc.intoArray(finalResult, i); + } + + // tail cleanup + for (; i < arr1.length; i++) { + finalResult[i] = (arr1[i] * arr1[i] + arr2[i] * arr2[i]) * -1.0f; + } + return finalResult; + } + + public double averageOfaVector(int[] arr) { + double sum = 0; + for (int i = 0; i < arr.length; i += SPECIES.length()) { + var mask = SPECIES.indexInRange(i, arr.length); + var V = IntVector.fromArray(SPECIES, arr, i, mask); + sum += V.reduceLanes(VectorOperators.ADD, mask); + } + return sum / arr.length; + } +} diff --git a/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java b/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java new file mode 100644 index 0000000000..22b37a2b28 --- /dev/null +++ b/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.vectors; + +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +public class VectorAPIUnitTest { + VectorAPIExamples vector = new VectorAPIExamples(); + + @Test + public void whenTwoArraysProvided_thenVerifyScalarAdd() { + int[] arr1 = { 1, 2, 3, 4 }; + int[] arr2 = { 100, 200, 300, 400 }; + int[] result = { 101, 202, 303, 404 }; + assertArrayEquals(result, vector.addTwoScalarArrays(arr1, arr2)); + } + + @Test + public void whenTwoArraysProvided_thenVerifyVectorAdd() { + int[] arr1 = { 1, 2, 3, 4 }; + int[] arr2 = { 100, 200, 300, 400 }; + int[] result = { 101, 202, 303, 404 }; + assertArrayEquals(result, vector.addTwoVectorsWithMasks(arr1, arr2)); + } + + @Test + public void whenTwoValuesProvided_thenComputeScalarNorm() { + float[] arr1 = { 1, 2.3f }; + float[] arr2 = { 1.3f, 2.0f }; + float[] result = { -2.6899998f, -9.29f }; + Assertions.assertArrayEquals(result, vector.scalarNormOfTwoArrays(arr1, arr2)); + } + + @Test + public void whenTwoValuesProvided_thenComputeVectorNorm() { + float[] arr1 = { 1, 2.3f }; + float[] arr2 = { 1.3f, 2.0f }; + float[] result = { -2.6899998f, -9.29f }; + Assertions.assertArrayEquals(result, vector.vectorNormalForm(arr1, arr2)); + } + + @Test + public void whenArrayProvided_thenComputeVectorAverage() { + int[] arr = { 100, 200, 300, 400 }; + Assertions.assertEquals(250.0, vector.averageOfaVector(arr)); + } +} diff --git a/core-java-modules/core-java-20/src/main/java/com/baeldung/zipentries/ZipEntryReader.java b/core-java-modules/core-java-20/src/main/java/com/baeldung/zipentries/ZipEntryReader.java new file mode 100644 index 0000000000..a353837e08 --- /dev/null +++ b/core-java-modules/core-java-20/src/main/java/com/baeldung/zipentries/ZipEntryReader.java @@ -0,0 +1,31 @@ +package com.baeldung.zipentries; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Scanner; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class ZipEntryReader { + + public static void readZipEntries(String filePath) throws IOException { + try (ZipFile zipFile = new ZipFile(filePath)) { + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + // Check if entry is a directory + if (!entry.isDirectory()) { + // Read and process the entry contents using the inputStream + try (InputStream inputStream = zipFile.getInputStream(entry); + Scanner scanner = new Scanner(inputStream);) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + System.out.println(line); + } + } + } + } + } + } +} diff --git a/core-java-modules/core-java-20/src/test/java/com/baeldung/zipentries/ZipEntryReaderUnitTest.java b/core-java-modules/core-java-20/src/test/java/com/baeldung/zipentries/ZipEntryReaderUnitTest.java new file mode 100644 index 0000000000..b21470baea --- /dev/null +++ b/core-java-modules/core-java-20/src/test/java/com/baeldung/zipentries/ZipEntryReaderUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.zipentries; + +import org.junit.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class ZipEntryReaderUnitTest { + + @Test + public void givenZipFile_thenReadEntriesAndValidateContent() throws URISyntaxException, IOException { + Path zipFilePath = Paths.get(getClass().getClassLoader().getResource("zipFile.zip").toURI()); + ZipEntryReader.readZipEntries(zipFilePath.toString()); + } +} diff --git a/core-java-modules/core-java-20/src/test/resources/zipFile.zip b/core-java-modules/core-java-20/src/test/resources/zipFile.zip new file mode 100644 index 0000000000..3fc509651f Binary files /dev/null and b/core-java-modules/core-java-20/src/test/resources/zipFile.zip differ diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 56f66c10fb..b860ca979d 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -3,4 +3,6 @@ - [Generating Random Dates in Java](https://www.baeldung.com/java-random-dates) - [Creating a LocalDate with Values in Java](https://www.baeldung.com/java-creating-localdate-with-values) - [Parsing Date Strings with Varying Formats](https://www.baeldung.com/java-parsing-dates-many-formats) +- [How Many Days Are There in a Particular Month of a Given Year?](https://www.baeldung.com/days-particular-month-given-year) +- [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/instantvslocaldatetime/InstantAndLocalDateTimeUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/instantvslocaldatetime/InstantAndLocalDateTimeUnitTest.java new file mode 100644 index 0000000000..74be3efe84 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/instantvslocaldatetime/InstantAndLocalDateTimeUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.instantvslocaldatetime; + +import org.junit.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class InstantAndLocalDateTimeUnitTest { + + @Test + public void givenTwoInstants_whenComparing_thenDifferent() { + + // Instant arithmetic + Instant.now().plus(12, ChronoUnit.HOURS); + Instant oneWeekAgo = Instant.now().minus(7, ChronoUnit.DAYS); + + // Comparing 2 Instants + Instant instant1 = Instant.now(); + Instant instant2 = instant1.plus(1, ChronoUnit.SECONDS); + assertTrue(instant1.isBefore(instant2)); + assertFalse(instant1.isAfter(instant2)); + } + + @Test + public void givenTwoLocalDateTimes_whenComparing_thenDifferent() { + + // LocalDateTime arithmetic + LocalDateTime tomorrow = LocalDateTime.now().plus(1, ChronoUnit.DAYS); + LocalDateTime oneYearAgo = LocalDateTime.now().minus(1, ChronoUnit.YEARS); + + // Comparing 2 LocalDateTimes + LocalDateTime now = LocalDateTime.now(); + LocalDateTime y2k = LocalDateTime.of(2000, 1, 1, 0, 0); + assertTrue(now.isAfter(y2k)); + assertTrue(y2k.isBefore(now)); + } +} diff --git a/core-java-modules/core-java-arrays-convert/README.md b/core-java-modules/core-java-arrays-convert/README.md index 4365fd12f9..fecbcfb698 100644 --- a/core-java-modules/core-java-arrays-convert/README.md +++ b/core-java-modules/core-java-arrays-convert/README.md @@ -7,3 +7,4 @@ This module contains articles about arrays conversion in Java - [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array) - [Convert a Byte Array to a Numeric Representation in Java](https://www.baeldung.com/java-byte-array-to-number) - [Converting a String Array Into an int Array in Java](https://www.baeldung.com/java-convert-string-array-to-int-array) +- [Convert Java Array to Iterable](https://www.baeldung.com/java-array-convert-to-iterable) diff --git a/core-java-modules/core-java-arrays-convert/src/main/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtils.java b/core-java-modules/core-java-arrays-convert/src/main/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtils.java new file mode 100644 index 0000000000..79f15e0ddd --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/main/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtils.java @@ -0,0 +1,28 @@ +package com.baeldung.array.conversions; + + +import com.google.common.primitives.Ints; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class IntArrayToIterableConversionUtils { + + public static Iterable convertWithStreamToList(int[] array) { + return Arrays.stream(array).boxed().collect(Collectors.toList()); + } + + public static Iterable convertWithStreamIterator(int[] array) { + return () -> Arrays.stream(array).iterator(); + } + + public static Iterable convertWithApacheCommonsAndJavaAsList(int[] array) { + return Arrays.asList(ArrayUtils.toObject(array)); + } + + public static Iterable convertWithGuava(int[] array) { + return Ints.asList(array); + } + +} diff --git a/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtilsUnitTest.java b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtilsUnitTest.java new file mode 100644 index 0000000000..f9d8c0db5a --- /dev/null +++ b/core-java-modules/core-java-arrays-convert/src/test/java/com/baeldung/array/conversions/IntArrayToIterableConversionUtilsUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.array.conversions; + +import org.junit.jupiter.api.Test; + +import static com.baeldung.array.conversions.IntArrayToIterableConversionUtils.*; +import static org.junit.Assert.assertTrue; + + +class IntArrayToIterableConversionUtilsUnitTest { + + private int[] ints = new int[]{1, 2, 3, 4, 5}; + + @Test + void whenConvertWithStreamToList_thenGetIterable() { + Iterable integers = convertWithStreamToList(ints); + assertTrue("should be Iterable", integers instanceof Iterable); + } + + @Test + void whenConvertWithStreamIterator_thenGetIterable() { + Iterable integers = convertWithStreamIterator(ints); + assertTrue("should be Iterable", integers instanceof Iterable); + } + + @Test + void whenConvertWithApacheCommonsAndJavaAsList_thenGetIterable() { + Iterable integers = convertWithApacheCommonsAndJavaAsList(ints); + assertTrue("should be Iterable", integers instanceof Iterable); + } + + @Test + void whenConvertWithGuava_thenGetIterable() { + Iterable integers = convertWithGuava(ints); + assertTrue("should be Iterable", integers instanceof Iterable); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-operations-advanced/README.md b/core-java-modules/core-java-arrays-operations-advanced/README.md index 1f55338644..e3465c9fa3 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/README.md +++ b/core-java-modules/core-java-arrays-operations-advanced/README.md @@ -12,3 +12,4 @@ This module contains articles about advanced operations on arrays in Java. They - [Concatenate Two Arrays in Java](https://www.baeldung.com/java-concatenate-arrays) - [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) - [Slicing Arrays in Java](https://www.baeldung.com/java-slicing-arrays) +- [Combining Two or More Byte Arrays](https://www.baeldung.com/java-concatenate-byte-arrays) diff --git a/core-java-modules/core-java-booleans/README.md b/core-java-modules/core-java-booleans/README.md index fe7068c6f4..9a4c948256 100644 --- a/core-java-modules/core-java-booleans/README.md +++ b/core-java-modules/core-java-booleans/README.md @@ -4,3 +4,4 @@ This module contains articles about Java Booleans. ### Relevant Articles: - [Convert Boolean to String in Java](https://www.baeldung.com/java-convert-boolean-to-string) +- [Difference Between Boolean.TRUE and true in Java](https://www.baeldung.com/java-boolean-true-primitive-vs-constant) diff --git a/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanTrueVsTrueUnitTest.java b/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanTrueVsTrueUnitTest.java new file mode 100644 index 0000000000..d8c43913fb --- /dev/null +++ b/core-java-modules/core-java-booleans/src/test/java/com/baeldung/booleans/BooleanTrueVsTrueUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.booleans; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class BooleanTrueVsTrueUnitTest { + + + @Test + public void given_BooleanValues_whenUsingBooleanTrue_thenTestBooleanEquality() { + assertEquals(Boolean.TRUE, Boolean.valueOf(true)); + } + + @Test + public void given_BooleanValues_whenUsingBooleanTrue_thenTestBooleanIdentity() { + assertTrue(Boolean.TRUE == Boolean.valueOf(true)); + } + + @Test + public void given_TrueValue_whenUsingTrue_thenTestPrimitiveEquality() { + assertTrue(true == true); + } + + @Test + public void given_TrueStringValue_whenUsingBooleanTrue_thenTestBooleanToString() { + assertEquals("true", Boolean.TRUE.toString()); + } + + @Test + public void given_PrimitiveValue_whenUsingStringValueOf_thenTestPrimitiveToString() { + assertEquals("true", String.valueOf(true)); + } + +} diff --git a/core-java-modules/core-java-collections-conversions-2/README.md b/core-java-modules/core-java-collections-conversions-2/README.md index 904e876032..fe17af0a7a 100644 --- a/core-java-modules/core-java-collections-conversions-2/README.md +++ b/core-java-modules/core-java-collections-conversions-2/README.md @@ -11,4 +11,5 @@ This module contains articles about conversions among Collection types and array - [Iterate Over a Set in Java](https://www.baeldung.com/java-iterate-set) - [Convert a List of Integers to a List of Strings](https://www.baeldung.com/java-convert-list-integers-to-list-strings) - [Combining Two Lists Into a Map in Java](https://www.baeldung.com/java-combine-two-lists-into-map) +- [Convert a List of Strings to a List of Integers](https://www.baeldung.com/java-convert-list-strings-to-integers) - More articles: [[<-- prev]](../core-java-collections-conversions) diff --git a/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/strlisttointlist/StringListToIntListUnitTest.java b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/strlisttointlist/StringListToIntListUnitTest.java new file mode 100644 index 0000000000..a29f32aecc --- /dev/null +++ b/core-java-modules/core-java-collections-conversions-2/src/test/java/com/baeldung/strlisttointlist/StringListToIntListUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.strlisttointlist; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; + +public class StringListToIntListUnitTest { + private final static List STRING_LIST = Arrays.asList("1", "2", "3", "4", "5", "6", "7"); + private final static List EXPECTED_LIST = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + + @Test + void whenUsingStream_thenGetExpectedIntegerList() { + List result = STRING_LIST.stream() + .map(Integer::valueOf) + .collect(Collectors.toList()); + assertEquals(EXPECTED_LIST, result); + } + + @Test + void whenUsingLoop_thenGetExpectedIntegerList() { + List result = new ArrayList<>(STRING_LIST.size()); + for (String s : STRING_LIST) { + result.add(Integer.valueOf(s)); + } + assertEquals(EXPECTED_LIST, result); + } + + @Test + void whenUsingGuava_thenGetExpectedIntegerList() { + List result = Lists.transform(STRING_LIST, new Function() { + @Override + public Integer apply(String input) { + return Integer.valueOf(input); + } + }); + assertEquals(EXPECTED_LIST, result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-5/README.md b/core-java-modules/core-java-collections-list-5/README.md index 947cf234b9..99563c3103 100644 --- a/core-java-modules/core-java-collections-list-5/README.md +++ b/core-java-modules/core-java-collections-list-5/README.md @@ -10,3 +10,4 @@ This module contains articles about the Java List collection - [Array vs. List Performance in Java](https://www.baeldung.com/java-array-vs-list-performance) - [Set Default Value for Elements in List](https://www.baeldung.com/java-list-set-default-values) - [Get Unique Values From an ArrayList In Java](https://www.baeldung.com/java-unique-values-arraylist) +- [Converting a Java List to a Json Array](https://www.baeldung.com/java-converting-list-to-json-array) diff --git a/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Benchmark.java b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Benchmark.java new file mode 100644 index 0000000000..964f6b3e3d --- /dev/null +++ b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Benchmark.java @@ -0,0 +1,14 @@ +package com.baeldung.concurrent.parallel; + +import java.io.IOException; + +class Benchmark { + + public static void main(String[] args) { + try { + org.openjdk.jmh.Main.main(new String[]{"com.baeldung.concurrent.parallel.Processor"}); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Processor.java b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Processor.java new file mode 100644 index 0000000000..747ae568b0 --- /dev/null +++ b/core-java-modules/core-java-concurrency-2/src/main/java/com/baeldung/concurrent/parallel/Processor.java @@ -0,0 +1,73 @@ +package com.baeldung.concurrent.parallel; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class Processor { + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void processSerially() throws InterruptedException { + for (int i = 0; i < 100; i++) { + Thread.sleep(10); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void processParallelyWithExecutorService() throws InterruptedException { + ExecutorService executorService = Executors.newFixedThreadPool(10); + List> futures = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + CompletableFuture future = CompletableFuture.runAsync(() -> { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }, executorService); + futures.add(future); + } + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + executorService.shutdown(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void processParallelyWithStream() { + IntStream.range(0, 100) + .parallel() + .forEach(i -> { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public void processParallelyWithStreamSupport() { + Iterable iterable = () -> IntStream.range(0, 100).iterator(); + Stream stream = StreamSupport.stream(iterable.spliterator(), true); + stream.forEach(i -> { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java index 933a1b5f52..9c880025f7 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java @@ -17,22 +17,21 @@ public class Consumer implements Runnable { public void consume() { while (dataQueue.runFlag) { - synchronized (dataQueue) { - while (dataQueue.isEmpty() && dataQueue.runFlag) { - try { - dataQueue.waitOnEmpty(); - } catch (InterruptedException e) { - e.printStackTrace(); - break; - } - } - if (!dataQueue.runFlag) { + while (dataQueue.isEmpty() && dataQueue.runFlag) { + try { + dataQueue.waitOnEmpty(); + } catch (InterruptedException e) { + e.printStackTrace(); break; } - Message message = dataQueue.remove(); - dataQueue.notifyAllForFull(); - useMessage(message); } + if (!dataQueue.runFlag) { + break; + } + Message message = dataQueue.remove(); + dataQueue.notifyAllForFull(); + useMessage(message); + } log.info("Consumer Stopped"); } @@ -40,7 +39,7 @@ public class Consumer implements Runnable { private void useMessage(Message message) { if (message != null) { log.info(String.format("[%s] Consuming Message. Id: %d, Data: %f%n", - Thread.currentThread().getName(), message.getId(), message.getData())); + Thread.currentThread().getName(), message.getId(), message.getData())); //Sleeping on random time to make it realistic ThreadUtil.sleep((long) (message.getData() * 100)); diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java index ca89d0c866..5ca60a29e4 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java @@ -19,22 +19,21 @@ public class Producer implements Runnable { public void produce() { while (dataQueue.runFlag) { - synchronized (dataQueue) { - while (dataQueue.isFull() && dataQueue.runFlag) { - try { - dataQueue.waitOnFull(); - } catch (InterruptedException e) { - e.printStackTrace(); - break; - } - } - if (!dataQueue.runFlag) { + while (dataQueue.isFull() && dataQueue.runFlag) { + try { + dataQueue.waitOnFull(); + } catch (InterruptedException e) { + e.printStackTrace(); break; } - Message message = generateMessage(); - dataQueue.add(message); - dataQueue.notifyAllForEmpty(); } + if (!dataQueue.runFlag) { + break; + } + Message message = generateMessage(); + dataQueue.add(message); + dataQueue.notifyAllForEmpty(); + } log.info("Producer Stopped"); } @@ -42,7 +41,7 @@ public class Producer implements Runnable { private Message generateMessage() { Message message = new Message(incrementAndGetId(), Math.random()); log.info(String.format("[%s] Generated Message. Id: %d, Data: %f%n", - Thread.currentThread().getName(), message.getId(), message.getData())); + Thread.currentThread().getName(), message.getId(), message.getData())); //Sleeping on random time to make it realistic ThreadUtil.sleep((long) (message.getData() * 100)); diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java new file mode 100644 index 0000000000..1f3997768e --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/completablefuture/threadpool/CustomCompletableFuture.java @@ -0,0 +1,28 @@ +package com.baeldung.concurrent.completablefuture.threadpool; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.function.Supplier; + +public class CustomCompletableFuture extends CompletableFuture { + private static final Executor executor = Executors.newSingleThreadExecutor(runnable -> new Thread(runnable, "Custom-Single-Thread")); + + public static CustomCompletableFuture supplyAsync(Supplier supplier) { + CustomCompletableFuture future = new CustomCompletableFuture<>(); + executor.execute(() -> { + try { + future.complete(supplier.get()); + } catch (Exception ex) { + future.completeExceptionally(ex); + } + }); + return future; + } + + @Override + public Executor defaultExecutor() { + return executor; + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/threadpool/CompletableFutureThreadPoolUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/threadpool/CompletableFutureThreadPoolUnitTest.java new file mode 100644 index 0000000000..9deadfb906 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/completablefuture/threadpool/CompletableFutureThreadPoolUnitTest.java @@ -0,0 +1,88 @@ +package com.baeldung.concurrent.completablefuture.threadpool; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import org.junit.jupiter.api.Test; + +public class CompletableFutureThreadPoolUnitTest { + + @Test + void whenUsingNonAsync_thenUsesMainThread() throws ExecutionException, InterruptedException { + CompletableFuture name = CompletableFuture.supplyAsync(() -> "Baeldung"); + + CompletableFuture nameLength = name.thenApply(value -> { + printCurrentThread(); + return value.length(); + }); + + assertThat(nameLength.get()).isEqualTo(8); + } + + @Test + void whenUsingNonAsync_thenUsesCallersThread() throws InterruptedException { + Runnable test = () -> { + CompletableFuture name = CompletableFuture.supplyAsync(() -> "Baeldung"); + + CompletableFuture nameLength = name.thenApply(value -> { + printCurrentThread(); + return value.length(); + }); + + try { + assertThat(nameLength.get()).isEqualTo(8); + } catch (Exception e) { + fail(e.getMessage()); + } + }; + + new Thread(test, "test-thread").start(); + Thread.sleep(100l); + } + + @Test + void whenUsingAsync_thenUsesCommonPool() throws ExecutionException, InterruptedException { + CompletableFuture name = CompletableFuture.supplyAsync(() -> "Baeldung"); + + CompletableFuture nameLength = name.thenApplyAsync(value -> { + printCurrentThread(); + return value.length(); + }); + + assertThat(nameLength.get()).isEqualTo(8); + } + + @Test + void whenUsingAsync_thenUsesCustomExecutor() throws ExecutionException, InterruptedException { + Executor testExecutor = Executors.newFixedThreadPool(5); + CompletableFuture name = CompletableFuture.supplyAsync(() -> "Baeldung"); + + CompletableFuture nameLength = name.thenApplyAsync(value -> { + printCurrentThread(); + return value.length(); + }, testExecutor); + + assertThat(nameLength.get()).isEqualTo(8); + } + + @Test + void whenOverridingDefaultThreadPool_thenUsesCustomExecutor() throws ExecutionException, InterruptedException { + CompletableFuture name = CustomCompletableFuture.supplyAsync(() -> "Baeldung"); + + CompletableFuture nameLength = name.thenApplyAsync(value -> { + printCurrentThread(); + return value.length(); + }); + + assertThat(nameLength.get()).isEqualTo(8); + } + + private static void printCurrentThread() { + System.out.println(Thread.currentThread().getName()); + } +} diff --git a/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/anonymousthread/AnonymousThreadUnitTest.java b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/anonymousthread/AnonymousThreadUnitTest.java new file mode 100644 index 0000000000..c292b480cf --- /dev/null +++ b/core-java-modules/core-java-concurrency-simple/src/test/java/com/baeldung/concurrent/anonymousthread/AnonymousThreadUnitTest.java @@ -0,0 +1,112 @@ +package com.baeldung.concurrent.anonymousthread; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class AnonymousThreadUnitTest { + static ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + static PrintStream printStream = new PrintStream(outputStream); + static List expectedNumbers = new ArrayList<>(); + + @BeforeClass + public static void setupClass() { + for (int i = 1; i <= 10; i++) { + expectedNumbers.add(String.valueOf(i)); + } + } + + @Before + public void setupMethod() { + System.setOut(printStream); + } + + @After + public void cleanUpMethod() { + outputStream.reset(); + System.setOut(System.out); + } + + @AfterClass + public static void cleanupClass() throws IOException { + expectedNumbers.clear(); + outputStream.close(); + printStream.close(); + } + + @Test + public void givenAnonymousThreadSubclassOverridingRunMethod_whenStart_thenRunAsExpected() { + Thread anonymousThread = new Thread() { + @Override + public void run() { + printNumbersFrom1To10(); + } + }; + anonymousThread.start(); + waitForThreadToFinish(); + anonymousThread.interrupt(); + + String[] printedNumbers = getPrintedNumbers(); + assertEquals(expectedNumbers, List.of(printedNumbers)); + } + + @Test + public void givenAnonymousThreadWithLambdaExpression_whenStart_thenRunAsExpected() { + Thread anonymousThread = new Thread(() -> { + printNumbersFrom1To10(); + }); + + anonymousThread.start(); + waitForThreadToFinish(); + anonymousThread.interrupt(); + + String[] printedNumbers = getPrintedNumbers(); + assertEquals(expectedNumbers, List.of(printedNumbers)); + } + + @Test + public void givenAnonymousThreadWithRunnableObject_whenStart_thenRunAsExpected() { + Thread anonymousThread = new Thread(new Runnable() { + @Override + public void run() { + printNumbersFrom1To10(); + } + }); + anonymousThread.start(); + waitForThreadToFinish(); + anonymousThread.interrupt(); + + String[] printedNumbers = getPrintedNumbers(); + assertEquals(expectedNumbers, List.of(printedNumbers)); + } + + private void printNumbersFrom1To10() { + for (int i = 1; i <= 10; i++) { + System.out.println(i); + } + } + + private void waitForThreadToFinish() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignore + } + } + + private String[] getPrintedNumbers() { + String printedOutput = outputStream.toString() + .trim(); + return printedOutput.split(System.lineSeparator()); + } +} diff --git a/core-java-modules/core-java-console/pom.xml b/core-java-modules/core-java-console/pom.xml index 4debf9388b..9ba1b55188 100644 --- a/core-java-modules/core-java-console/pom.xml +++ b/core-java-modules/core-java-console/pom.xml @@ -19,6 +19,16 @@ jansi 2.4.0 + + org.junit.vintage + junit-vintage-engine + + + junit + junit + + + @@ -70,6 +80,16 @@ ${target.version} + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + junit-vintage-engine + + + diff --git a/core-java-modules/core-java-console/src/test/java/com/baeldung/asciiart/AsciiArtIntegrationTest.java b/core-java-modules/core-java-console/src/test/java/com/baeldung/asciiart/AsciiArtIntegrationTest.java index a8c42fbeb1..4274551cf8 100644 --- a/core-java-modules/core-java-console/src/test/java/com/baeldung/asciiart/AsciiArtIntegrationTest.java +++ b/core-java-modules/core-java-console/src/test/java/com/baeldung/asciiart/AsciiArtIntegrationTest.java @@ -1,9 +1,10 @@ package com.baeldung.asciiart; -import com.baeldung.asciiart.AsciiArt.Settings; -import org.junit.Test; +import java.awt.Font; -import java.awt.*; +import org.junit.jupiter.api.Test; + +import com.baeldung.asciiart.AsciiArt.Settings; public class AsciiArtIntegrationTest { @@ -12,7 +13,7 @@ public class AsciiArtIntegrationTest { AsciiArt asciiArt = new AsciiArt(); String text = "BAELDUNG"; Settings settings = asciiArt.new Settings(new Font("SansSerif", Font.BOLD, 24), text.length() * 30, 30); // 30 pixel width per character - + asciiArt.drawString(text, "*", settings); } } diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index 0d36f9c8a2..c87714f38a 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -6,4 +6,6 @@ This module contains articles about date operations in Java. - [Create Date From Unix Timestamp in Java](https://www.baeldung.com/java-date-unix-timestamp) - [Convert java.util.Date to java.sql.Date](https://www.baeldung.com/java-convert-util-date-to-sql) - [How to Determine Date of the First Day of the Week Using LocalDate in Java](https://www.baeldung.com/java-first-day-of-the-week) +- [Adding One Month to Current Date in Java](https://www.baeldung.com/java-adding-one-month-to-current-date) +- [How to Get Last Day of a Month in Java](https://www.baeldung.com/java-last-day-month) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) diff --git a/core-java-modules/core-java-date-operations-3/pom.xml b/core-java-modules/core-java-date-operations-3/pom.xml index 89c21a31c1..19760ca357 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -12,5 +12,23 @@ core-java-modules 0.0.1-SNAPSHOT + + + + joda-time + joda-time + ${joda-time.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + 2.12.5 + 3.12.0 + \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/lastdaymonth/LastDayOfMonth.java b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/lastdaymonth/LastDayOfMonth.java new file mode 100644 index 0000000000..0dc8304309 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/lastdaymonth/LastDayOfMonth.java @@ -0,0 +1,32 @@ +package com.baeldung.lastdaymonth; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.temporal.TemporalAdjusters; +import java.util.Calendar; + +public class LastDayOfMonth { + + static int getLastDayOfMonthUsingCalendar(int month) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.MONTH, month); + return cal.getActualMaximum(Calendar.DAY_OF_MONTH); + } + + static int getLastDayOfMonthUsingTemporalAdjusters(LocalDate date) { + return date.with(TemporalAdjusters.lastDayOfMonth()) + .getDayOfMonth(); + } + + static int getLastDayOfMonthUsingYearMonth(YearMonth date) { + return date.atEndOfMonth() + .getDayOfMonth(); + } + + static int getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate date) { + return date.dayOfMonth() + .withMaximumValue() + .getDayOfMonth(); + } + +} diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/date/AddOneMonthToCurrentDateUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/date/AddOneMonthToCurrentDateUnitTest.java new file mode 100644 index 0000000000..7b15fadd03 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/date/AddOneMonthToCurrentDateUnitTest.java @@ -0,0 +1,79 @@ +package com.baeldung.date; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.apache.commons.lang3.time.DateUtils; +import org.junit.jupiter.api.Test; + +class AddOneMonthToCurrentDateUnitTest { + + @Test + void givenCalendarDate_whenAddingOneMonth_thenDateIsChangedCorrectly() { + Calendar calendar = Calendar.getInstance(); + // Dummy current date + calendar.set(2023, Calendar.APRIL, 20); + + // add one month + calendar.add(Calendar.MONTH, 1); + + assertEquals(Calendar.MAY, calendar.get(Calendar.MONTH)); + assertEquals(20, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(2023, calendar.get(Calendar.YEAR)); + } + + @SuppressWarnings("deprecation") + @Test + void givenDate_whenAddingOneMonth_thenDateIsChangedCorrectly() { + // Dummy current date + Date currentDate = new Date(2023, Calendar.DECEMBER, 20); + // Expected Date + Date expectedDate = new Date(2024, Calendar.JANUARY, 20); + + // add one month + currentDate.setMonth(currentDate.getMonth() + 1); + + assertEquals(expectedDate, currentDate); + } + + @Test + void givenJavaLocalDate_whenAddingOneMonth_thenDateIsChangedCorrectly() { + // Dummy current date + LocalDate localDate = LocalDate.of(2023, 12, 20); + + // add one month + localDate = localDate.plusMonths(1); + + assertEquals(1, localDate.getMonthValue()); + assertEquals(20, localDate.getDayOfMonth()); + assertEquals(2024, localDate.getYear()); + } + + @Test + void givenJodaTimeLocalDate_whenAddingOneMonth_thenDateIsChangedCorrectly() { + // Dummy current date + org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 12, 20); + + // add one month + localDate = localDate.plusMonths(1); + + assertEquals(1, localDate.getMonthOfYear()); + assertEquals(20, localDate.getDayOfMonth()); + assertEquals(2024, localDate.getYear()); + } + + @Test + void givenApacheCommonsLangDateUtils_whenAddingOneMonth_thenDateIsChangedCorrectly() { + // Dummy current date + Date currentDate = new GregorianCalendar(2023, Calendar.APRIL, 20, 4, 0).getTime(); + // Expected Date + Date expectedDate = new GregorianCalendar(2023, Calendar.MAY, 20, 4, 0).getTime(); + + assertEquals(expectedDate, DateUtils.addMonths(currentDate, 1)); + } + +} diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/lastdaymonth/LastDayOfMonthUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/lastdaymonth/LastDayOfMonthUnitTest.java new file mode 100644 index 0000000000..ea9a02c484 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/lastdaymonth/LastDayOfMonthUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.lastdaymonth; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.time.LocalDate; +import java.time.YearMonth; + +import org.junit.jupiter.api.Test; + +class LastDayOfMonthUnitTest { + + @Test + void givenMonth_whenUsingCalendar_thenReturnLastDay() { + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingCalendar(0)); + assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingCalendar(3)); + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingCalendar(9)); + } + + @Test + void givenMonth_whenUsingTemporalAdjusters_thenReturnLastDay() { + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 1, 1))); + assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 4, 1))); + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingTemporalAdjusters(LocalDate.of(2023, 10, 1))); + } + + @Test + void givenMonth_whenUsingYearMonth_thenReturnLastDay() { + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 1))); + assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 4))); + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingYearMonth(YearMonth.of(2023, 10))); + } + + @Test + void givenMonth_whenUsingJodaTime_thenReturnLastDay() { + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-1-1"))); + assertEquals(30, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-4-1"))); + assertEquals(31, LastDayOfMonth.getLastDayOfMonthUsingJodaTime(org.joda.time.LocalDate.parse("2023-10-1"))); + } + +} diff --git a/core-java-modules/core-java-datetime-string-2/README.md b/core-java-modules/core-java-datetime-string-2/README.md index d59f3b3fca..6ff19a44ab 100644 --- a/core-java-modules/core-java-datetime-string-2/README.md +++ b/core-java-modules/core-java-datetime-string-2/README.md @@ -4,3 +4,4 @@ This module contains articles about parsing and formatting Java date and time ob ### Relevant Articles: - [Convert String to Instant](https://www.baeldung.com/java-string-to-instant) +- [Sort Date Strings in Java](https://www.baeldung.com/java-sort-date-strings) diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java index 06b7d38821..62f0d9da22 100644 --- a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/BufferedReaderUnitTest.java @@ -3,18 +3,23 @@ package com.baeldung.bufferedreadervsfilereader; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.BufferedReader; -import java.io.FileReader; +import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; -import org.junit.jupiter.api.Assertions; -import org.testng.annotations.Test; -public class BufferedReaderUnitTest { +import org.junit.jupiter.api.Test; + +class BufferedReaderUnitTest { @Test - public void whenReadingAFile_thenReadsLineByLine() { + void whenReadingAFile_thenReadsLineByLine() { StringBuilder result = new StringBuilder(); - try (BufferedReader br = new BufferedReader(new FileReader("src/test/resources/sampleText1.txt"))) { + final Path filePath = new File("src/test/resources/sampleText1.txt").toPath(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(Files.newInputStream(filePath), StandardCharsets.UTF_8))) { String line; while((line = br.readLine()) != null) { diff --git a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java index 5df870e7b5..da724d32e8 100644 --- a/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java +++ b/core-java-modules/core-java-io-apis-2/src/test/java/com/baeldung/bufferedreadervsfilereader/FileReaderUnitTest.java @@ -7,10 +7,10 @@ import java.io.IOException; import org.junit.jupiter.api.Test; -public class FileReaderUnitTest { +class FileReaderUnitTest { @Test - public void whenReadingAFile_thenReadsCharByChar() { + void whenReadingAFile_thenReadsCharByChar() { StringBuilder result = new StringBuilder(); try (FileReader fr = new FileReader("src/test/resources/sampleText2.txt")) { diff --git a/core-java-modules/core-java-io-apis-3/README.md b/core-java-modules/core-java-io-apis-3/README.md new file mode 100644 index 0000000000..23f2b41ac7 --- /dev/null +++ b/core-java-modules/core-java-io-apis-3/README.md @@ -0,0 +1,6 @@ +## Core Java IO APIs + +This module contains articles about core Java input/output(IO) APIs. + +### Relevant Articles: +- [Read Date in Java Using Scanner](https://www.baeldung.com/java-scanner-read-date) diff --git a/core-java-modules/core-java-io-apis-3/pom.xml b/core-java-modules/core-java-io-apis-3/pom.xml new file mode 100644 index 0000000000..8b2431397b --- /dev/null +++ b/core-java-modules/core-java-io-apis-3/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + core-java-io-apis-3 + core-java-io-apis-3 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-3/src/main/java/com/baeldung/scanner/DateScanner.java b/core-java-modules/core-java-io-apis-3/src/main/java/com/baeldung/scanner/DateScanner.java new file mode 100644 index 0000000000..a9f3ba820a --- /dev/null +++ b/core-java-modules/core-java-io-apis-3/src/main/java/com/baeldung/scanner/DateScanner.java @@ -0,0 +1,29 @@ +package com.baeldung.scanner; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Scanner; + +public class DateScanner { + + LocalDate scanToLocalDate(String input) { + try (Scanner scanner = new Scanner(input)) { + String dateString = scanner.next(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return LocalDate.parse(dateString, formatter); + } + } + + Date scanToDate(String input) throws ParseException { + try (Scanner scanner = new Scanner(input)) { + String dateString = scanner.next(); + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + return formatter.parse(dateString); + } + } + +} diff --git a/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/emptyfile/CheckFileIsEmptyUnitTest.java b/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/emptyfile/CheckFileIsEmptyUnitTest.java new file mode 100644 index 0000000000..0603a298f5 --- /dev/null +++ b/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/emptyfile/CheckFileIsEmptyUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.emptyfile; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +public class CheckFileIsEmptyUnitTest { + @Test + void whenTheFileIsEmpty_thenFileLengthIsZero(@TempDir Path tempDir) throws IOException { + File emptyFile = tempDir.resolve("an-empty-file.txt") + .toFile(); + emptyFile.createNewFile(); + assertTrue(emptyFile.exists()); + assertEquals(0, emptyFile.length()); + } + + @Test + void whenFileDoesNotExist_thenFileLengthIsZero(@TempDir Path tempDir) { + File aNewFile = tempDir.resolve("a-new-file.txt") + .toFile(); + assertFalse(aNewFile.exists()); + assertEquals(0, aNewFile.length()); + } + + boolean isFileEmpty(File file) { + if (!file.exists()) { + throw new IllegalArgumentException("Cannot check the file length. The file is not found: " + file.getAbsolutePath()); + } + return file.length() == 0; + } + + @Test + void whenTheFileDoesNotExist_thenIsFilesEmptyThrowsException(@TempDir Path tempDir) { + File aNewFile = tempDir.resolve("a-new-file.txt") + .toFile(); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> isFileEmpty(aNewFile)); + assertEquals(ex.getMessage(), "Cannot check the file length. The file is not found: " + aNewFile.getAbsolutePath()); + } + + @Test + void whenTheFileIsEmpty_thenIsFilesEmptyReturnsTrue(@TempDir Path tempDir) throws IOException { + File emptyFile = tempDir.resolve("an-empty-file.txt") + .toFile(); + emptyFile.createNewFile(); + assertTrue(isFileEmpty(emptyFile)); + + } + + @Test + void whenTheFileIsEmpty_thenFilesSizeReturnsTrue(@TempDir Path tempDir) throws IOException { + Path emptyFilePath = tempDir.resolve("an-empty-file.txt"); + Files.createFile(emptyFilePath); + assertEquals(0, Files.size(emptyFilePath)); + } + + @Test + void whenTheFileDoesNotExist_thenFilesSizeThrowsException(@TempDir Path tempDir) { + Path aNewFilePath = tempDir.resolve("a-new-file.txt"); + assertThrows(NoSuchFileException.class, () -> Files.size(aNewFilePath)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/scanner/DateScannerUnitTest.java b/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/scanner/DateScannerUnitTest.java new file mode 100644 index 0000000000..1ecd440d95 --- /dev/null +++ b/core-java-modules/core-java-io-apis-3/src/test/java/com/baeldung/scanner/DateScannerUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +import org.junit.jupiter.api.Test; + +class DateScannerUnitTest { + + @Test + void whenScanToLocalDate_ThenCorrectLocalDate() { + String dateString = "2018-09-09"; + assertEquals(LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd")), new DateScanner().scanToLocalDate(dateString)); + } + + @Test + void whenScanToDate_ThenCorrectDate() throws ParseException { + String dateString = "2018-09-09"; + assertEquals(new SimpleDateFormat("yyyy-MM-dd").parse(dateString), new DateScanner().scanToDate(dateString)); + } + +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Course.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Course.java new file mode 100644 index 0000000000..f8367cfd50 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Course.java @@ -0,0 +1,42 @@ +package com.baeldung.deepcopyarraylist; + +import java.io.Serializable; + +public class Course implements Serializable, Cloneable { + + private Integer courseId; + private String courseName; + + public Course() { + } + + public Course(Integer courseId, String courseName) { + this.courseId = courseId; + this.courseName = courseName; + } + + public Integer getCourseId() { + return courseId; + } + + public void setCourseId(Integer courseId) { + this.courseId = courseId; + } + + public String getCourseName() { + return courseName; + } + + public void setCourseName(String courseName) { + this.courseName = courseName; + } + + @Override + public Course clone() { + try { + return (Course) super.clone(); + } catch (CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Student.java b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Student.java new file mode 100644 index 0000000000..0b3f1ba4a9 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/main/java/com/baeldung/deepcopyarraylist/Student.java @@ -0,0 +1,103 @@ +package com.baeldung.deepcopyarraylist; + +import java.io.Serializable; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.SerializationUtils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Student implements Serializable, Cloneable { + + private int studentId; + private String studentName; + private Course course; + + public Student() { + } + + public Student(int studentId, String studentName, Course course) { + this.studentId = studentId; + this.studentName = studentName; + this.course = course; + } + + public Student(Student student) { + this.studentId = student.getStudentId(); + this.studentName = student.getStudentName(); + this.course = new Course(student.getCourse() + .getCourseId(), student.getCourse() + .getCourseName()); + } + + public static Student createDeepCopy(Student student) { + ObjectMapper objectMapper = new ObjectMapper(); + try { + return objectMapper.readValue(objectMapper.writeValueAsString(student), Student.class); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException(e); + } + } + + public static List deepCopyUsingJackson(List students) { + return students.stream() + .map(Student::createDeepCopy) + .collect(Collectors.toList()); + } + + public static List deepCopyUsingCloneable(List students) { + return students.stream() + .map(Student::clone) + .collect(Collectors.toList()); + } + + public static List deepCopyUsingCopyConstructor(List students) { + return students.stream() + .map(Student::new) + .collect(Collectors.toList()); + } + + public static List deepCopyUsingSerialization(List students) { + return students.stream() + .map(SerializationUtils::clone) + .collect(Collectors.toList()); + } + + public int getStudentId() { + return studentId; + } + + public void setStudentId(int studentId) { + this.studentId = studentId; + } + + public String getStudentName() { + return studentName; + } + + public void setStudentName(String studentName) { + this.studentName = studentName; + } + + public Course getCourse() { + return course; + } + + public void setCourse(Course course) { + this.course = course; + } + + @Override + public Student clone() { + Student student; + try { + student = (Student) super.clone(); + } catch (CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + student.course = this.course.clone(); + return student; + } +} diff --git a/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/deepcopyarraylist/DeepCopyArrayListUnitTest.java b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/deepcopyarraylist/DeepCopyArrayListUnitTest.java new file mode 100644 index 0000000000..625c7e8385 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-patterns/src/test/java/com/baeldung/deepcopyarraylist/DeepCopyArrayListUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.deepcopyarraylist; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +public class DeepCopyArrayListUnitTest { + + @Test + public void whenCreatingCopyWithCloneable_thenObjectsShouldNotBeSame() { + Course course = new Course(1, "Spring Masterclass"); + Student student1 = new Student(1, "John", course); + Student student2 = new Student(2, "David", course); + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + List deepCopy = Student.deepCopyUsingCloneable(students); + + Assertions.assertNotEquals(students.get(0), deepCopy.get(0)); + Assertions.assertNotEquals(students.get(1), deepCopy.get(1)); + + } + + @Test + public void whenCreatingDeepCopyWithCopyConstructor_thenObjectsShouldNotBeSame() { + + Course course = new Course(1, "Spring Masterclass"); + Student student1 = new Student(1, "John", course); + Student student2 = new Student(2, "David", course); + + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + List deepCopy = Student.deepCopyUsingCopyConstructor(students); + + Assertions.assertNotEquals(students.get(0), deepCopy.get(0)); + Assertions.assertNotEquals(students.get(1), deepCopy.get(1)); + } + + @Test + public void whenCreatingDeepCopyWithSerializationUtils_thenObjectsShouldNotBeSame() { + + Course course = new Course(1, "Spring Masterclass"); + Student student1 = new Student(1, "John", course); + Student student2 = new Student(2, "David", course); + + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + List deepCopy = Student.deepCopyUsingSerialization(students); + + Assertions.assertNotEquals(students.get(0), deepCopy.get(0)); + Assertions.assertNotEquals(students.get(1), deepCopy.get(1)); + } + + @Test + public void whenCreatingDeepCopyWithJackson_thenObjectsShouldNotBeSame() { + + Course course = new Course(1, "Spring Masterclass"); + Student student1 = new Student(1, "John", course); + Student student2 = new Student(2, "David", course); + + List students = new ArrayList<>(); + students.add(student1); + students.add(student2); + + List deepCopy = Student.deepCopyUsingJackson(students); + + Assertions.assertNotEquals(students.get(0), deepCopy.get(0)); + Assertions.assertNotEquals(students.get(1), deepCopy.get(1)); + } +} diff --git a/core-java-modules/core-java-methods/README.md b/core-java-modules/core-java-methods/README.md index b2208778e7..3f4202dd0e 100644 --- a/core-java-modules/core-java-methods/README.md +++ b/core-java-modules/core-java-methods/README.md @@ -3,4 +3,4 @@ ## Core Java Methods ### Relevant Articles: -- [Execute a Method Only Once in Java](https://www.baeldung.com/execute-a-method-only-once-in-java) \ No newline at end of file +- [Execute a Method Only Once in Java](https://www.baeldung.com/java-execute-method-only-once) diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md index 222834d06b..91f48ff547 100644 --- a/core-java-modules/core-java-security-3/README.md +++ b/core-java-modules/core-java-security-3/README.md @@ -13,4 +13,5 @@ This module contains articles about core Java Security - [Error: “trustAnchors parameter must be non-empty”](https://www.baeldung.com/java-trustanchors-parameter-must-be-non-empty) - [Common Exceptions of Crypto APIs in Java](https://www.baeldung.com/java-crypto-apis-exceptions) - [Hashing With Argon2 in Java](https://www.baeldung.com/java-argon2-hashing) +- [Hex Representation of a SHA-1 Digest of a String in Java](https://www.baeldung.com/java-string-sha1-hexadecimal) - More articles: [[<-- prev]](/core-java-modules/core-java-security-2) diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index a4f60b4db5..ad9feeb36a 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -30,6 +30,11 @@ jaxb-api ${jaxb-api.version} + + com.google.guava + guava + ${google-guava.version} + org.springframework.security spring-security-crypto @@ -39,9 +44,10 @@ 1.70 - 1.11 + 1.15 2.3.1 6.0.3 + 31.0.1-jre \ No newline at end of file diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/sha1/HexRepresentationSha1DigestUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/sha1/HexRepresentationSha1DigestUnitTest.java new file mode 100644 index 0000000000..f2c346707e --- /dev/null +++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/crypto/sha1/HexRepresentationSha1DigestUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.crypto.sha1; + +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.jupiter.api.Test; + +import com.google.common.hash.Hashing; + +public class HexRepresentationSha1DigestUnitTest { + + String input = "Hello, World"; + String expectedHexValue = "907d14fb3af2b0d4f18c2d46abe8aedce17367bd"; + + @Test + public void givenMessageDigest_whenUpdatingWithData_thenDigestShouldMatchExpectedValue() throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + md.update(input.getBytes(StandardCharsets.UTF_8)); + + StringBuilder hexString = new StringBuilder(); + byte[] digest = md.digest(); + + for (byte b : digest) { + hexString.append(String.format("%02x", b)); + } + assertEquals(expectedHexValue, hexString.toString()); + } + + @Test + public void givenDigestUtils_whenCalculatingSHA1Hex_thenDigestShouldMatchExpectedValue() { + assertEquals(expectedHexValue, DigestUtils.sha1Hex(input)); + } + + @Test + public void givenHashingLibrary_whenCalculatingSHA1Hash_thenDigestShouldMatchExpectedValue() { + assertEquals(expectedHexValue, Hashing.sha1().hashString(input, StandardCharsets.UTF_8).toString()); + } +} diff --git a/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/SingletonUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/SingletonUnitTest.java index d5133ae976..3d233327e3 100644 --- a/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/SingletonUnitTest.java +++ b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/SingletonUnitTest.java @@ -1,47 +1,70 @@ package com.baeldung.readresolvevsreadobject; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; + +import org.junit.After; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; public class SingletonUnitTest { + private static final String SINGLETON_SER = "singleton.ser"; + + @After + public void tearDown() { + final File file = new File(SINGLETON_SER); + if (file.exists()) { + file.deleteOnExit(); + } + } + @Test public void testSingletonObj_withNoReadResolve() throws ClassNotFoundException, IOException { // Serialization - FileOutputStream fos = new FileOutputStream("singleton.ser"); + FileOutputStream fos = new FileOutputStream(SINGLETON_SER); ObjectOutputStream oos = new ObjectOutputStream(fos); Singleton actualSingletonObject = Singleton.getInstance(); oos.writeObject(actualSingletonObject); // Deserialization Singleton deserializedSingletonObject = null; - FileInputStream fis = new FileInputStream("singleton.ser"); + FileInputStream fis = new FileInputStream(SINGLETON_SER); ObjectInputStream ois = new ObjectInputStream(fis); deserializedSingletonObject = (Singleton) ois.readObject(); // remove readResolve() from Singleton class and uncomment this to test. //assertNotEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode()); + + fos.close(); + oos.close(); + fis.close(); + ois.close(); } @Test public void testSingletonObj_withCustomReadResolve() throws ClassNotFoundException, IOException { // Serialization - FileOutputStream fos = new FileOutputStream("singleton.ser"); + FileOutputStream fos = new FileOutputStream(SINGLETON_SER); ObjectOutputStream oos = new ObjectOutputStream(fos); Singleton actualSingletonObject = Singleton.getInstance(); oos.writeObject(actualSingletonObject); // Deserialization - Singleton deserializedSingletonObject = null; - FileInputStream fis = new FileInputStream("singleton.ser"); + Singleton deserializedSingletonObject; + FileInputStream fis = new FileInputStream(SINGLETON_SER); ObjectInputStream ois = new ObjectInputStream(fis); deserializedSingletonObject = (Singleton) ois.readObject(); assertEquals(actualSingletonObject.hashCode(), deserializedSingletonObject.hashCode()); + + fos.close(); + oos.close(); + fis.close(); + ois.close(); } } diff --git a/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/UserUnitTest.java b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/UserUnitTest.java index ffd56d67e9..cd07fd2bc7 100644 --- a/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/UserUnitTest.java +++ b/core-java-modules/core-java-serialization/src/test/java/com/baeldung/readresolvevsreadobject/UserUnitTest.java @@ -1,52 +1,74 @@ package com.baeldung.readresolvevsreadobject; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; + +import org.junit.After; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; public class UserUnitTest { + private static final String USER_SER = "user.ser"; + + @After + public void tearDown() { + final File file = new File(USER_SER); + if (file.exists()) { + file.deleteOnExit(); + } + } + @Test - public void testDeserializeObj_withOverriddenReadObject() - throws ClassNotFoundException, IOException { + public void testDeserializeObj_withOverriddenReadObject() throws ClassNotFoundException, IOException { // Serialization - FileOutputStream fos = new FileOutputStream("user.ser"); + FileOutputStream fos = new FileOutputStream(USER_SER); ObjectOutputStream oos = new ObjectOutputStream(fos); User acutalObject = new User("Sachin", "Kumar"); oos.writeObject(acutalObject); // Deserialization - User deserializedUser = null; - FileInputStream fis = new FileInputStream("user.ser"); + User deserializedUser; + FileInputStream fis = new FileInputStream(USER_SER); ObjectInputStream ois = new ObjectInputStream(fis); deserializedUser = (User) ois.readObject(); assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode()); assertEquals(deserializedUser.getUserName(), "Sachin"); assertEquals(deserializedUser.getPassword(), "Kumar"); + + fos.close(); + oos.close(); + fis.close(); + ois.close(); } @Test public void testDeserializeObj_withDefaultReadObject() throws ClassNotFoundException, IOException { // Serialization - FileOutputStream fos = new FileOutputStream("user.ser"); + FileOutputStream fos = new FileOutputStream(USER_SER); ObjectOutputStream oos = new ObjectOutputStream(fos); User acutalObject = new User("Sachin", "Kumar"); oos.writeObject(acutalObject); // Deserialization - User deserializedUser = null; - FileInputStream fis = new FileInputStream("user.ser"); + User deserializedUser; + FileInputStream fis = new FileInputStream(USER_SER); ObjectInputStream ois = new ObjectInputStream(fis); deserializedUser = (User) ois.readObject(); assertNotEquals(deserializedUser.hashCode(), acutalObject.hashCode()); assertEquals(deserializedUser.getUserName(), "Sachin"); // remove readObject() from User class and uncomment this to test. //assertEquals(deserializedUser.getPassword(), "xyzKumar"); + + fos.close(); + oos.close(); + fis.close(); + ois.close(); } } diff --git a/core-java-modules/core-java-streams-collect/pom.xml b/core-java-modules/core-java-streams-collect/pom.xml index e81598017c..427fcbdf8d 100644 --- a/core-java-modules/core-java-streams-collect/pom.xml +++ b/core-java-modules/core-java-streams-collect/pom.xml @@ -3,7 +3,7 @@ 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"> 4.0.0 - core-java-streams-4 + core-java-streams-collect core-java-streams-collect jar diff --git a/core-java-modules/core-java-string-apis-2/README.md b/core-java-modules/core-java-string-apis-2/README.md index d1ec0d8388..38bfb70ef1 100644 --- a/core-java-modules/core-java-string-apis-2/README.md +++ b/core-java-modules/core-java-string-apis-2/README.md @@ -5,3 +5,5 @@ This module contains articles about string APIs. ### Relevant Articles: - [Retain Only Digits and Decimal Separator in String](https://www.baeldung.com/java-string-retain-digits-decimal) - [Difference Between null and Empty String in Java](https://www.baeldung.com/java-string-null-vs-empty) +- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) +- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) \ No newline at end of file diff --git a/core-java-modules/core-java-string-apis-2/pom.xml b/core-java-modules/core-java-string-apis-2/pom.xml index db97b85748..51ab3bc1f8 100644 --- a/core-java-modules/core-java-string-apis-2/pom.xml +++ b/core-java-modules/core-java-string-apis-2/pom.xml @@ -24,6 +24,11 @@ commons-lang3 ${commons.lang3.version} + + com.ibm.icu + icu4j + ${icu4j.version} + @@ -39,6 +44,7 @@ 3.12.0 31.1-jre + 61.1 \ No newline at end of file diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/App.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/App.java similarity index 100% rename from core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/App.java rename to core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/App.java diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/ICUFormat.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/ICUFormat.java similarity index 100% rename from core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/ICUFormat.java rename to core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/ICUFormat.java diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/JavaSEFormat.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/JavaSEFormat.java similarity index 100% rename from core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/JavaSEFormat.java rename to core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/JavaSEFormat.java diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/Localization.java b/core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/Localization.java similarity index 100% rename from core-java-modules/core-java-strings/src/main/java/com/baeldung/localization/Localization.java rename to core-java-modules/core-java-string-apis-2/src/main/java/com/baeldung/localization/Localization.java diff --git a/core-java-modules/core-java-strings/src/main/resources/formats_en.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/formats_en.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/formats_en.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/formats_en.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/formats_fr.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/formats_fr.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/formats_fr.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/formats_fr.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/formats_it.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/formats_it.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/formats_it.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/formats_it.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/formats_pl.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/formats_pl.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/formats_pl.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/formats_pl.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/messages_en.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/messages_en.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/messages_en.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/messages_en.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/messages_fr.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/messages_fr.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/messages_fr.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/messages_fr.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/messages_it.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/messages_it.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/messages_it.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/messages_it.properties diff --git a/core-java-modules/core-java-strings/src/main/resources/messages_pl.properties b/core-java-modules/core-java-string-apis-2/src/main/resources/messages_pl.properties similarity index 100% rename from core-java-modules/core-java-strings/src/main/resources/messages_pl.properties rename to core-java-modules/core-java-string-apis-2/src/main/resources/messages_pl.properties diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java similarity index 100% rename from core-java-modules/core-java-strings/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java rename to core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/localization/ICUFormatUnitTest.java diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java b/core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java similarity index 100% rename from core-java-modules/core-java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java rename to core-java-modules/core-java-string-apis-2/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index cc755cf470..5cd1bd3c56 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -29,6 +29,11 @@ commons-lang3 ${apache-commons-lang3.version} + + org.apache.commons + commons-text + ${apache-commons-text.version} + org.assertj assertj-core @@ -56,6 +61,7 @@ 4.1 5.3.13 3.12.0 + 1.10.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java index 843aaac0b5..a278041b8b 100644 --- a/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java +++ b/core-java-modules/core-java-string-operations-4/src/test/java/com/baeldung/namedformatting/NamedFormatterUnitTest.java @@ -1,6 +1,6 @@ package com.baeldung.namedformatting; -import org.apache.commons.text.StrSubstitutor; +import org.apache.commons.text.StringSubstitutor; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -12,20 +12,20 @@ class NamedFormatterUnitTest { private static final String TEMPLATE = "Text: [${text}] Number: [${number}] Text again: [${text}]"; @Test - void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutor_shouldGetExpectedResult() { + void givenTemplateWithNamedParam_whenCallingCommonsTextStringSubstitutor_shouldGetExpectedResult() { Map params = new HashMap<>(); params.put("text", "It's awesome!"); params.put("number", 42); - String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + String result = StringSubstitutor.replace(TEMPLATE, params, "${", "}"); assertThat(result).isEqualTo("Text: [It's awesome!] Number: [42] Text again: [It's awesome!]"); } @Test - void givenTemplateWithNamedParam_whenCallingCommonsTextStrSubstitutorWithParameterNames_shouldNotWorkAsExpected() { + void givenTemplateWithNamedParam_whenCallingCommonsTextStringSubstitutorWithParameterNames_shouldNotWorkAsExpected() { Map params = new HashMap<>(); params.put("text", "'${number}' is a placeholder."); params.put("number", 42); - String result = StrSubstitutor.replace(TEMPLATE, params, "${", "}"); + String result = StringSubstitutor.replace(TEMPLATE, params, "${", "}"); assertThat(result).isNotEqualTo("Text: ['${number}' is a placeholder.] Number: [42] Text again: ['${number}' is a placeholder.]"); diff --git a/core-java-modules/core-java-string-operations-6/README.md b/core-java-modules/core-java-string-operations-6/README.md index 190880a5dd..e866f50860 100644 --- a/core-java-modules/core-java-string-operations-6/README.md +++ b/core-java-modules/core-java-string-operations-6/README.md @@ -2,3 +2,7 @@ ### Relevant Articles: - [Find the Longest Word in a Given String in Java](https://www.baeldung.com/java-longest-word-string) +- [Check if a String Is All Uppercase or Lowercase in Java](https://www.baeldung.com/java-check-string-uppercase-lowercase) +- [Java – Generate Random String](https://www.baeldung.com/java-random-string) +- [Fixing “constant string too long” Build Error](https://www.baeldung.com/java-constant-string-too-long-error) +- [Compact Strings in Java 9](https://www.baeldung.com/java-9-compact-string) \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/pom.xml b/core-java-modules/core-java-string-operations-6/pom.xml index 8b9eabbc63..0ec32d91b1 100644 --- a/core-java-modules/core-java-string-operations-6/pom.xml +++ b/core-java-modules/core-java-string-operations-6/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 core-java-string-operations-6 core-java-string-operations-6 @@ -12,6 +12,23 @@ core-java-modules 0.0.1-SNAPSHOT + + + org.apache.commons + commons-lang3 + ${apache.commons-lang.version} + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + @@ -29,6 +46,8 @@ 11 11 + 3.12.0 + 1.36 \ No newline at end of file diff --git a/core-java-modules/core-java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java b/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java similarity index 100% rename from core-java-modules/core-java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java rename to core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java diff --git a/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexChecker.java b/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexChecker.java new file mode 100644 index 0000000000..2d56213c31 --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexChecker.java @@ -0,0 +1,50 @@ +package com.baeldung.nonalphanumeric; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NonAlphaNumRegexChecker { + + private static final Pattern PATTERN_NON_ALPHNUM_ANYLANG = Pattern.compile("[^\\p{IsAlphabetic}\\p{IsDigit}]"); + private static final Pattern PATTERN_NON_ALPHNUM_USASCII = Pattern.compile("[^a-zA-Z0-9]+"); + /** + * checks if a non-alphanumeric character is present. this method would return true if + * it comes across a non english or non US-ASCII letter + * + * @param str - String to check for special character + * @return true if special character found else false + */ + public static boolean isNonAlphanumeric(String str) { +// Pattern pattern = Pattern.compile("\\W"); //same as [^a-zA-Z0-9]+ +// Pattern pattern = Pattern.compile("[^a-zA-Z0-9||\\s]+"); //ignores space + Matcher matcher = PATTERN_NON_ALPHNUM_USASCII.matcher(str); + return matcher.find(); + } + + /** + * Checks for non-alphanumeric characters from all language scripts + * + * @param input - String to check for special character + * @return true if special character found else false + */ + public static boolean containsNonAlphanumeric(String input) { +// Pattern pattern = Pattern.compile("[^\\p{Alnum}]", Pattern.UNICODE_CHARACTER_CLASS); //Binary properties + Matcher matcher = PATTERN_NON_ALPHNUM_ANYLANG.matcher(input); + return matcher.find(); + } + + /** + * checks for non-alphanumeric character. it returns true if it detects any character other than the + * specified script argument. example of script - Character.UnicodeScript.GEORGIAN.name() + * + * @param input - String to check for special character + * @param script - language script + * @return true if special character found else false + */ + public static boolean containsNonAlphanumeric(String input, String script) { + String regexScriptClass = "\\p{" + "Is" + script + "}"; + Pattern pattern = Pattern.compile("[^" + regexScriptClass + "\\p{IsDigit}]"); //Binary properties + Matcher matcher = pattern.matcher(input); + return matcher.find(); + } +} diff --git a/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumericChecker.java b/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumericChecker.java new file mode 100644 index 0000000000..e9458459eb --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/main/java/com/baeldung/nonalphanumeric/NonAlphaNumericChecker.java @@ -0,0 +1,49 @@ +package com.baeldung.nonalphanumeric; + +import org.apache.commons.lang3.StringUtils; + +public class NonAlphaNumericChecker { + /** + * Checks for non-alphanumeric characters in any Unicode Script + * @param str - String to check for special characters + * @return true if special character found else false + */ + public static boolean isNonAlphanumericAnyLangScript(String str) { + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (!Character.isLetterOrDigit(c)) { + return true; + } + } + return false; + } + + /** + * checks for special characters,returns false if any character + * found other than the script argument + * @param str - String to check for special characters + * @param script - Language script + * @return true if special character found else false + */ + public static boolean isNonAlphanumericInLangScript(String str, String script) { + + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); +// script e.g., Character.UnicodeScript.of(c).toString().equalsIgnoreCase(Character.UnicodeScript.LATIN.toString()) + if (!Character.UnicodeScript.of(c).toString().equalsIgnoreCase(script) + && !Character.isDigit(c)) { + return true; + } + } + return false; + } + + /** + * checks for special characters in any lang + * @param str - String to check for special characters + * @return true if special character found else false + */ + public static boolean isNonAlphanumericAnyLangScriptV2(String str) { + return !StringUtils.isAlphanumeric(str); + } +} diff --git a/core-java-modules/core-java-strings/src/main/resources/config.properties b/core-java-modules/core-java-string-operations-6/src/main/resources/config.properties similarity index 99% rename from core-java-modules/core-java-strings/src/main/resources/config.properties rename to core-java-modules/core-java-string-operations-6/src/main/resources/config.properties index 8197c13543..088ed029d7 100644 --- a/core-java-modules/core-java-strings/src/main/resources/config.properties +++ b/core-java-modules/core-java-string-operations-6/src/main/resources/config.properties @@ -1 +1 @@ -string.too.long= StringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLong +string.too.long= StringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLongStringTooLong diff --git a/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/checkcase/StringAllUpperOrLowercaseUnitTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/checkcase/StringAllUpperOrLowercaseUnitTest.java new file mode 100644 index 0000000000..6dec5af29a --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/checkcase/StringAllUpperOrLowercaseUnitTest.java @@ -0,0 +1,104 @@ +package com.baeldung.checkcase; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; + +class CaseChecker { + + static boolean allUpper1(String input) { + return input.equals(input.toUpperCase()); + } + + static boolean allLower1(String input) { + return input.equals(input.toLowerCase()); + } + + static boolean allUpper2(String input) { + for (char c : input.toCharArray()) { + // don't write in this way: if (!Character.isUpperCase(c)) + if (Character.isLowerCase(c)) { + return false; + } + } + return true; + } + + static boolean allLower2(String input) { + for (char c : input.toCharArray()) { + // don't write in this way: if (!Character.isLowerCase(c)) + if (Character.isUpperCase(c)) { + return false; + } + } + return true; + } + + static boolean allUpper3(String input) { + return input.chars() + .noneMatch(Character::isLowerCase); + } + + static boolean allLower3(String input) { + return input.chars() + .noneMatch(Character::isUpperCase); + } +} + +public class StringAllUpperOrLowercaseUnitTest { + private static final String UPPER_INPUT = "1: COOL!"; + private static final String LOWER_INPUT = "2: cool!"; + private static final String MIXED_INPUT = "3: Cool!"; + + @Test + void whenComparingToConvertedString_thenGetExpectedResult() { + assertTrue(CaseChecker.allLower1(LOWER_INPUT)); + assertFalse(CaseChecker.allLower1(UPPER_INPUT)); + assertFalse(CaseChecker.allLower1(MIXED_INPUT)); + + assertFalse(CaseChecker.allUpper1(LOWER_INPUT)); + assertTrue(CaseChecker.allUpper1(UPPER_INPUT)); + assertFalse(CaseChecker.allUpper1(MIXED_INPUT)); + } + + @Test + void whenCheckCharInArray_thenGetExpectedResult() { + assertTrue(CaseChecker.allLower2(LOWER_INPUT)); + assertFalse(CaseChecker.allLower2(UPPER_INPUT)); + assertFalse(CaseChecker.allLower2(MIXED_INPUT)); + + assertFalse(CaseChecker.allUpper2(LOWER_INPUT)); + assertTrue(CaseChecker.allUpper2(UPPER_INPUT)); + assertFalse(CaseChecker.allUpper2(MIXED_INPUT)); + } + + @Test + void whenUsingStream_thenGetExpectedResult() { + assertTrue(CaseChecker.allLower3(LOWER_INPUT)); + assertFalse(CaseChecker.allLower3(UPPER_INPUT)); + assertFalse(CaseChecker.allLower3(MIXED_INPUT)); + + assertFalse(CaseChecker.allUpper3(LOWER_INPUT)); + assertTrue(CaseChecker.allUpper3(UPPER_INPUT)); + assertFalse(CaseChecker.allUpper3(MIXED_INPUT)); + } + + @Test + void whenUsingApacheCommons_thenGetExpectedResult() { + assertFalse(StringUtils.isAllLowerCase(LOWER_INPUT)); + assertFalse(StringUtils.isAllLowerCase(UPPER_INPUT)); + assertFalse(StringUtils.isAllLowerCase(MIXED_INPUT)); + + assertFalse(StringUtils.isAllLowerCase("a b")); + assertTrue(StringUtils.isAllLowerCase("ab")); + + assertFalse(StringUtils.isAllUpperCase(LOWER_INPUT)); + assertFalse(StringUtils.isAllUpperCase(UPPER_INPUT)); + assertFalse(StringUtils.isAllUpperCase(MIXED_INPUT)); + + assertFalse(StringUtils.isAllUpperCase("A B")); + assertTrue(StringUtils.isAllUpperCase("AB")); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/BenchmarkLiveTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/BenchmarkLiveTest.java new file mode 100644 index 0000000000..7c5c8101f8 --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/BenchmarkLiveTest.java @@ -0,0 +1,47 @@ +package com.baeldung.digitsandnondigits; + +import static com.baeldung.digitsandnondigits.SplitDigitsAndNondigitsUnitTest.parseString; + +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +@State(Scope.Benchmark) +@Threads(1) +@BenchmarkMode(Mode.Throughput) +@Fork(warmups = 1, value = 1) +@Warmup(iterations = 2, time = 10, timeUnit = TimeUnit.MILLISECONDS) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class BenchmarkLiveTest { + private static final String INPUT = "01Michael Jackson23Michael Jordan42Michael Bolton999Michael Johnson000"; + + @Param({ "10000" }) + public int iterations; + + @Benchmark + public void regexBased(Blackhole blackhole) { + blackhole.consume(INPUT.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")); + } + + @Benchmark + public void nonRegexBased(Blackhole blackhole) { + blackhole.consume(parseString(INPUT)); + } + + @Test + public void benchmark() throws Exception { + String[] argv = {}; + org.openjdk.jmh.Main.main(argv); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/SplitDigitsAndNondigitsUnitTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/SplitDigitsAndNondigitsUnitTest.java new file mode 100644 index 0000000000..55e0e48070 --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/digitsandnondigits/SplitDigitsAndNondigitsUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.digitsandnondigits; + +import static com.baeldung.digitsandnondigits.SplitDigitsAndNondigitsUnitTest.State.INIT; +import static com.baeldung.digitsandnondigits.SplitDigitsAndNondigitsUnitTest.State.PARSING_DIGIT; +import static com.baeldung.digitsandnondigits.SplitDigitsAndNondigitsUnitTest.State.PARSING_NON_DIGIT; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class SplitDigitsAndNondigitsUnitTest { + private static final String INPUT1 = "01Michael Jackson23Michael Jordan42Michael Bolton999Michael Johnson000"; + private static final String[] EXPECTED1 = new String[] { "01", "Michael Jackson", "23", "Michael Jordan", "42", "Michael Bolton", "999", "Michael Johnson", "000" }; + private static final List EXPECTED_LIST1 = Arrays.asList(EXPECTED1); + + private static final String INPUT2 = "Michael Jackson01Michael Jordan23Michael Bolton42Michael Johnson999Great Michaels"; + private static final String[] EXPECTED2 = new String[] { "Michael Jackson", "01", "Michael Jordan", "23", "Michael Bolton", "42", "Michael Johnson", "999", "Great Michaels" }; + private static final List EXPECTED_LIST2 = Arrays.asList(EXPECTED2); + + @Test + void whenUsingLookaroundRegex_thenGetExpectedResult() { + String splitRE = "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"; + String[] result1 = INPUT1.split(splitRE); + assertArrayEquals(EXPECTED1, result1); + + String[] result2 = INPUT2.split(splitRE); + assertArrayEquals(EXPECTED2, result2); + } + + enum State { + INIT, PARSING_DIGIT, PARSING_NON_DIGIT + } + + static List parseString(String input) { + List result = new ArrayList<>(); + int start = 0; + State state = INIT; + for (int i = 0; i < input.length(); i++) { + if (input.charAt(i) >= '0' && input.charAt(i) <= '9') { + if (state == PARSING_NON_DIGIT) { + result.add(input.substring(start, i)); + start = i; + } + state = PARSING_DIGIT; + } else { + if (state == PARSING_DIGIT) { + result.add(input.substring(start, i)); + start = i; + } + state = PARSING_NON_DIGIT; + } + } + result.add(input.substring(start)); + return result; + } + + @Test + void whenCheckEachChar_thenGetExpectedResult() { + List result1 = parseString(INPUT1); + assertEquals(EXPECTED_LIST1, result1); + + List result2 = parseString(INPUT2); + assertEquals(EXPECTED_LIST2, result2); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexCheckerUnitTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexCheckerUnitTest.java new file mode 100644 index 0000000000..67d3d3c00c --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumRegexCheckerUnitTest.java @@ -0,0 +1,117 @@ +package com.baeldung.nonalphanumeric; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class NonAlphaNumRegexCheckerUnitTest { + @Test + public void whenStrLatinOrHasNonAlphaNum_ThenRetTrue() { + //alphabets with special character + String str1 = "W$nder^ful"; + //digits with special character + String str2 = "123$%45"; + //alphabets and digits with special characters + String str3 = "W@nd$r123$%45"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumRegexChecker.isNonAlphanumeric(str1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumRegexChecker.isNonAlphanumeric(str2)); + assertTrue(ERROR_MSG + str3, NonAlphaNumRegexChecker.isNonAlphanumeric(str3)); + } + + @Test + public void whenStrLatinOrHasNoNonAlphaNum_ThenRetFalse() { + //only alphabets + String str1 = "Wonderful"; + //only digits + String str2 = "12345"; + //mix of alphabet and digit + String str3 = "5Won6der1234"; + //Error message + String ERROR_MSG = "Test failed, non alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumRegexChecker.isNonAlphanumeric(str1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumRegexChecker.isNonAlphanumeric(str2)); + assertFalse(ERROR_MSG + str3, NonAlphaNumRegexChecker.isNonAlphanumeric(str3)); + } + + @Test + public void whenStrNonLatinOrHasNonAlphaNum_ThenRetTrue() { + //special character in Georgian text + String str1 = "##მშვენიერი@"; + //special character with Turkish text + String str2 = "müthiş#$"; + //No special character in Georgian text + String str3 = "მშვენიერი"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumRegexChecker.isNonAlphanumeric(str1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumRegexChecker.isNonAlphanumeric(str2)); + assertTrue(ERROR_MSG + str3, NonAlphaNumRegexChecker.isNonAlphanumeric(str3)); + } + + @Test + public void whenStrAnyLangOrHasNonAlphaNum_ThenRetTrue() { + //special character in Georgian text + String str1 = "##მშვენიერი@"; + //special character with Turkish text + String str2 = "müthiş#$"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumRegexChecker.containsNonAlphanumeric(str1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumRegexChecker.containsNonAlphanumeric(str2)); + } + + @Test + public void whenStrAnyLangOrHasNoNonAlphaNum_ThenRetFalse() { + //Georgian text with no special char + String str1 = "მშვენიერი"; + //Turkish text with no special char + String str2 = "müthiş"; + //Latin text with no special char + String str3 = "Wonderful"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumRegexChecker.containsNonAlphanumeric(str1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumRegexChecker.containsNonAlphanumeric(str2)); + assertFalse(ERROR_MSG + str3, NonAlphaNumRegexChecker.containsNonAlphanumeric(str3)); + } + + @Test + public void givenLang_whenStrHasDiffLangOrHasNonAlphaNum_ThenRetTrue() { + String script1 = Character.UnicodeScript.MYANMAR.name(); //script used for Burmese Lang + //text in Burmese with special char + String str1 = "အံ့ဩ%စ##ရာ"; + //special character and english char in Burmese + String str2 = "အံ့ADFဩစ%ရာ*^"; + //English character in Burmese + String str3 = "အံ့ဩစTရာWon"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumRegexChecker.containsNonAlphanumeric(str1, script1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumRegexChecker.containsNonAlphanumeric(str2, script1)); + assertTrue(ERROR_MSG + str3, NonAlphaNumRegexChecker.containsNonAlphanumeric(str3, script1)); + } + + @Test + public void givenLang_whenStrHasSameLangOrHasNoNonAlphaNum_ThenRetFalse() { + String script1 = Character.UnicodeScript.MYANMAR.name(); //script used for Burmese Lang + String script2 = Character.UnicodeScript.GREEK.name(); + //text in Burmese + String str1 = "အံ့ဩစရာ"; + //text in Greek + String str2 = "Εκπληκτικός"; + //Error message + String ERROR_MSG = "Test failed, alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumRegexChecker.containsNonAlphanumeric(str1, script1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumRegexChecker.containsNonAlphanumeric(str2, script2)); + } +} diff --git a/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumericCheckerUnitTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumericCheckerUnitTest.java new file mode 100644 index 0000000000..3323377bcc --- /dev/null +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/nonalphanumeric/NonAlphaNumericCheckerUnitTest.java @@ -0,0 +1,159 @@ +package com.baeldung.nonalphanumeric; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class NonAlphaNumericCheckerUnitTest { + @Test + public void whenStrLatinOrHasNonAlphaNum_ThenRetTrue() { + String latin = Character.UnicodeScript.LATIN.name(); + //alphabets with special character + String str1 = "W$nder^ful"; + //digits with special character + String str2 = "123$%45"; + //alphabets and digits with special characters + String str3 = "W@nd$r123$%45"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str1, latin)); + assertTrue(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str2, latin)); + assertTrue(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str3, latin)); + } + + @Test + public void whenStrLatinOrHasNoNonAlphaNum_ThenRetFalse() { + String latin = Character.UnicodeScript.LATIN.name(); + //only alphabets + String str1 = "Wonderful"; + //only digits + String str2 = "12345"; + //mix of alphabet and digit + String str3 = "5Won6der1234"; + //Error message + String ERROR_MSG = "Test failed, non alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str1, latin)); + assertFalse(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str2, latin)); + assertFalse(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str3, latin)); + } + + @Test + public void whenStrNonLatinOrHasNonAlphaNum_ThenRetTrue() { + String latin = Character.UnicodeScript.LATIN.name(); + //special character in Georgian text + String str1 = "##მშვენიერი@"; + //special character with Turkish text + String str2 = "müthiş#$"; + //No special character in Georgian text + String str3 = "მშვენიერი"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str1, latin)); + assertTrue(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str2, latin)); + assertTrue(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str3, latin)); + } + + @Test + public void whenStrAnyLangOrHasNonAlphaNum_ThenRetTrue() { + //special character in Georgian text + String str1 = "##მშვენიერი@"; + //special character with Turkish text + String str2 = "müthiş#$"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericAnyLangScript(str1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericAnyLangScript(str2)); + } + + @Test + public void whenStrAnyLangOrHasNoNonAlphaNum_ThenRetFalse() { + //Georgian text with no special char + String str1 = "მშვენიერი"; + //Turkish text with no special char + String str2 = "müthiş"; + //Latin text with no special char + String str3 = "Wonderful"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericAnyLangScript(str1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericAnyLangScript(str2)); + assertFalse(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericAnyLangScript(str3)); + } + + @Test + public void givenLang_whenStrHasDiffLangOrHasNonAlphaNum_ThenRetTrue() { + String script1 = Character.UnicodeScript.MYANMAR.name(); //script used for Burmese Lang + //text in Burmese with special char + String str1 = "အံ့ဩ%စ##ရာ"; + //special character and english char in Burmese + String str2 = "အံ့ADFဩစ%ရာ*^"; + //English character in Burmese + String str3 = "အံ့ဩစTရာWon"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str1, script1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str2, script1)); + assertTrue(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str3, script1)); + } + + @Test + public void givenLang_whenStrHasSameLangOrHasNoNonAlphaNum_ThenRetFalse() { + String script1 = Character.UnicodeScript.MYANMAR.name(); //script used for Burmese Lang + String script2 = Character.UnicodeScript.GREEK.name(); + //text in Burmese + String str1 = "အံ့ဩစရာ"; + //text in Greek + String str2 = "Εκπληκτικός"; + //Error message + String ERROR_MSG = "Test failed, alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str1, script1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericInLangScript(str2, script2)); + } + + @Test + public void givenComLangImpl_whenStrAnyLangOrHasNonAlphaNum_ThenRetTrue() { + //special character in Georgian text + String str1 = "##მშვენიერი@"; + //special character with Turkish text + String str2 = "müthiş#$"; + //Error message + String ERROR_MSG = "Test failed, no alphanumeric char found in "; + + assertTrue(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str1)); + assertTrue(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str2)); + } + + @Test + public void givenComLangImpl_whenStrAnyLangOrHasNoNonAlphaNum_ThenRetFalse() { + //Georgian text with no special char + String str1 = "მშვენიერი"; + //Turkish text with no special char + String str2 = "müthiş"; + //Latin text with no special char + String str3 = "Wonderful"; + //Burmese in Myanmar script +// String str4 = "အံ့ဩစရာ"; + //only digits + String str5 = "3465"; + //Error message + String ERROR_MSG = "Test failed, alphanumeric char found in "; + + assertFalse(ERROR_MSG + str1, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str1)); + assertFalse(ERROR_MSG + str2, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str2)); + assertFalse(ERROR_MSG + str3, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str3)); + //StringUtils.isAlphanumeric is unable to support supplementary unicode character and hence fails + //assertFalse(ERROR_MSG + str4, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str4)); + assertFalse(ERROR_MSG + str5, NonAlphaNumericChecker.isNonAlphanumericAnyLangScriptV2(str5)); + } +} + + + diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java similarity index 97% rename from core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java rename to core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java index edfabc8777..8bc50be7e6 100644 --- a/core-java-modules/core-java-strings/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java +++ b/core-java-modules/core-java-string-operations-6/src/test/java/com/baeldung/randomstrings/RandomStringsUnitTest.java @@ -1,103 +1,103 @@ -package com.baeldung.randomstrings; - -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.charset.Charset; -import java.util.Random; - -public class RandomStringsUnitTest { - - private static final Logger LOG = LoggerFactory.getLogger(RandomStringsUnitTest.class); - - @Test - public void givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect() { - byte[] array = new byte[7]; // length is bounded by 7 - new Random().nextBytes(array); - String generatedString = new String(array, Charset.forName("UTF-8")); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingPlainJava_whenGeneratingRandomStringBounded_thenCorrect() { - int leftLimit = 97; // letter 'a' - int rightLimit = 122; // letter 'z' - int targetStringLength = 10; - Random random = new Random(); - StringBuilder buffer = new StringBuilder(targetStringLength); - - for (int i = 0; i < targetStringLength; i++) { - int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1)); - buffer.append((char) randomLimitedInt); - } - String generatedString = buffer.toString(); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingJava8_whenGeneratingRandomAlphabeticString_thenCorrect() { - int leftLimit = 97; // letter 'a' - int rightLimit = 122; // letter 'z' - int targetStringLength = 10; - Random random = new Random(); - - String generatedString = random.ints(leftLimit, rightLimit + 1) - .limit(targetStringLength) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingJava8_whenGeneratingRandomAlphanumericString_thenCorrect() { - int leftLimit = 48; // numeral '0' - int rightLimit = 122; // letter 'z' - int targetStringLength = 10; - Random random = new Random(); - - String generatedString = random.ints(leftLimit, rightLimit + 1) - .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) - .limit(targetStringLength) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomString_thenCorrect() { - String generatedString = RandomStringUtils.random(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomAlphabeticString_thenCorrect() { - String generatedString = RandomStringUtils.randomAlphabetic(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomAlphanumericString_thenCorrect() { - String generatedString = RandomStringUtils.randomAlphanumeric(10); - - LOG.debug(generatedString); - } - - @Test - public void givenUsingApache_whenGeneratingRandomStringBounded_thenCorrect() { - int length = 10; - boolean useLetters = true; - boolean useNumbers = false; - String generatedString = RandomStringUtils.random(length, useLetters, useNumbers); - - LOG.debug(generatedString); - } - -} +package com.baeldung.randomstrings; + +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.charset.Charset; +import java.util.Random; + +public class RandomStringsUnitTest { + + private static final Logger LOG = LoggerFactory.getLogger(RandomStringsUnitTest.class); + + @Test + public void givenUsingPlainJava_whenGeneratingRandomStringUnbounded_thenCorrect() { + byte[] array = new byte[7]; // length is bounded by 7 + new Random().nextBytes(array); + String generatedString = new String(array, Charset.forName("UTF-8")); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingPlainJava_whenGeneratingRandomStringBounded_thenCorrect() { + int leftLimit = 97; // letter 'a' + int rightLimit = 122; // letter 'z' + int targetStringLength = 10; + Random random = new Random(); + StringBuilder buffer = new StringBuilder(targetStringLength); + + for (int i = 0; i < targetStringLength; i++) { + int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1)); + buffer.append((char) randomLimitedInt); + } + String generatedString = buffer.toString(); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingJava8_whenGeneratingRandomAlphabeticString_thenCorrect() { + int leftLimit = 97; // letter 'a' + int rightLimit = 122; // letter 'z' + int targetStringLength = 10; + Random random = new Random(); + + String generatedString = random.ints(leftLimit, rightLimit + 1) + .limit(targetStringLength) + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) + .toString(); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingJava8_whenGeneratingRandomAlphanumericString_thenCorrect() { + int leftLimit = 48; // numeral '0' + int rightLimit = 122; // letter 'z' + int targetStringLength = 10; + Random random = new Random(); + + String generatedString = random.ints(leftLimit, rightLimit + 1) + .filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)) + .limit(targetStringLength) + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) + .toString(); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomString_thenCorrect() { + String generatedString = RandomStringUtils.random(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomAlphabeticString_thenCorrect() { + String generatedString = RandomStringUtils.randomAlphabetic(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomAlphanumericString_thenCorrect() { + String generatedString = RandomStringUtils.randomAlphanumeric(10); + + LOG.debug(generatedString); + } + + @Test + public void givenUsingApache_whenGeneratingRandomStringBounded_thenCorrect() { + int length = 10; + boolean useLetters = true; + boolean useNumbers = false; + String generatedString = RandomStringUtils.random(length, useLetters, useNumbers); + + LOG.debug(generatedString); + } + +} diff --git a/core-java-modules/core-java-strings/src/test/resources/stringtoolong.txt b/core-java-modules/core-java-string-operations-6/src/test/resources/stringtoolong.txt similarity index 100% rename from core-java-modules/core-java-strings/src/test/resources/stringtoolong.txt rename to core-java-modules/core-java-string-operations-6/src/test/resources/stringtoolong.txt diff --git a/core-java-modules/core-java-strings/README.md b/core-java-modules/core-java-strings/README.md index 84cf31e8bd..03e980e5a5 100644 --- a/core-java-modules/core-java-strings/README.md +++ b/core-java-modules/core-java-strings/README.md @@ -1,16 +1,16 @@ ## Java Strings -This module contains articles about strings in Java. +This is a generic module contains articles about strings in Java. +Listed here there are only those articles that does not fit into other core-java-string-* modules as: +- [core-java-string-operations](../core-java-string-operations) +- [core-java-string-apis](../core-java-string-apis) +- [core-java-string-conversion](../core-java-string-conversions) +- [core-java-string-algorithms](../core-java-string-algorithms) ### Relevant Articles: - [Use char[] Array Over a String for Manipulating Passwords in Java?](https://www.baeldung.com/java-storing-passwords) -- [Compact Strings in Java 9](https://www.baeldung.com/java-9-compact-string) - [String Not Empty Test Assertions in Java](https://www.baeldung.com/java-assert-string-not-empty) - [String Performance Hints](https://www.baeldung.com/java-string-performance) -- [Java Localization – Formatting Messages](https://www.baeldung.com/java-localization-messages-formatting) -- [Java – Generate Random String](https://www.baeldung.com/java-random-string) - [Java String Interview Questions and Answers](https://www.baeldung.com/java-string-interview-questions) - [Java Multi-line String](https://www.baeldung.com/java-multiline-string) -- [Guide to Java String Pool](https://www.baeldung.com/java-string-pool) -- [Fixing “constant string too long” Build Error](https://www.baeldung.com/java-constant-string-too-long-error) - [Reuse StringBuilder for Efficiency](https://www.baeldung.com/java-reuse-stringbuilder-for-efficiency) diff --git a/core-java-modules/core-java-strings/pom.xml b/core-java-modules/core-java-strings/pom.xml index e3cdb3c666..b43e7bfe73 100644 --- a/core-java-modules/core-java-strings/pom.xml +++ b/core-java-modules/core-java-strings/pom.xml @@ -29,11 +29,6 @@ jmh-generator-annprocess ${jmh-generator.version} - - com.ibm.icu - icu4j - ${icu4j.version} - @@ -47,7 +42,6 @@ - 61.1 15 diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 806882a84f..9144e16359 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -81,6 +81,7 @@ core-java-io-4 core-java-io-apis core-java-io-apis-2 + core-java-io-apis-3 core-java-io-conversions core-java-jar core-java-jndi diff --git a/gcp-firebase/pom.xml b/gcp-firebase/pom.xml index 10a899f370..c2dbfb813f 100644 --- a/gcp-firebase/pom.xml +++ b/gcp-firebase/pom.xml @@ -18,7 +18,6 @@ ${firebase-admin.version} - org.springframework.boot spring-boot-starter-web diff --git a/gradle-modules/gradle-7/README.md b/gradle-modules/gradle-7/README.md index 6e29e3db30..98fb968e82 100644 --- a/gradle-modules/gradle-7/README.md +++ b/gradle-modules/gradle-7/README.md @@ -5,3 +5,4 @@ - [Working With Multiple Repositories in Gradle](https://www.baeldung.com/java-gradle-multiple-repositories) - [Different Dependency Version Declarations in Gradle](https://www.baeldung.com/gradle-different-dependency-version-declarations) - [Generating Javadoc With Gradle](https://www.baeldung.com/java-gradle-javadoc) +- [Generating WSDL Stubs With Gradle](https://www.baeldung.com/java-gradle-create-wsdl-stubs) diff --git a/gradle-modules/gradle/maven-to-gradle/build.gradle b/gradle-modules/gradle/maven-to-gradle/build.gradle index f891e592c2..b213b8125f 100644 --- a/gradle-modules/gradle/maven-to-gradle/build.gradle +++ b/gradle-modules/gradle/maven-to-gradle/build.gradle @@ -1,9 +1,11 @@ /* * This file was generated by the Gradle 'init' task. + * + * This project uses @Incubating APIs which are subject to change. */ plugins { - id 'java' + id 'java-library' id 'maven-publish' } @@ -15,7 +17,7 @@ repositories { } dependencies { - implementation 'org.apache.commons:commons-lang3:3.12.0' + api 'org.apache.commons:commons-lang3:3.12.0' } group = 'com.baeldung' diff --git a/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2f..f03f475efe 100644 Binary files a/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.jar and b/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.properties index ba94df8451..38f7c5acfc 100644 --- a/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle/maven-to-gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-rc-2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle/maven-to-gradle/gradlew b/gradle-modules/gradle/maven-to-gradle/gradlew index 2fe81a7d95..fcb6fca147 100644 --- a/gradle-modules/gradle/maven-to-gradle/gradlew +++ b/gradle-modules/gradle/maven-to-gradle/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,110 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,87 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradle-modules/gradle/maven-to-gradle/gradlew.bat b/gradle-modules/gradle/maven-to-gradle/gradlew.bat index 9618d8d960..93e3f59f13 100644 --- a/gradle-modules/gradle/maven-to-gradle/gradlew.bat +++ b/gradle-modules/gradle/maven-to-gradle/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,10 +25,14 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -51,7 +55,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -61,38 +65,26 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/gradle-modules/gradle/maven-to-gradle/pom.xml b/gradle-modules/gradle/maven-to-gradle/pom.xml index 7a30c389da..786b5e4fbd 100644 --- a/gradle-modules/gradle/maven-to-gradle/pom.xml +++ b/gradle-modules/gradle/maven-to-gradle/pom.xml @@ -14,4 +14,9 @@ + + 17 + 17 + + \ No newline at end of file diff --git a/gradle-modules/gradle/maven-to-gradle/settings.gradle b/gradle-modules/gradle/maven-to-gradle/settings.gradle index 8a7251a5c2..655854407d 100644 --- a/gradle-modules/gradle/maven-to-gradle/settings.gradle +++ b/gradle-modules/gradle/maven-to-gradle/settings.gradle @@ -1,5 +1,7 @@ /* * This file was generated by the Gradle 'init' task. + * + * This project uses @Incubating APIs which are subject to change. */ rootProject.name = 'maven-to-gradle' diff --git a/guest/memory-leaks/pom.xml b/guest/memory-leaks/pom.xml index 0712e0627d..42bb71617d 100644 --- a/guest/memory-leaks/pom.xml +++ b/guest/memory-leaks/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 memory-leaks 0.0.1-SNAPSHOT diff --git a/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientParamsLiveTest.java b/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientParamsLiveTest.java index ef662e1bd8..7acdf2c091 100644 --- a/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientParamsLiveTest.java +++ b/httpclient-simple/src/test/java/com/baeldung/httpclient/HttpClientParamsLiveTest.java @@ -3,7 +3,6 @@ package com.baeldung.httpclient; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; - import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -13,10 +12,9 @@ import java.util.List; import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; -import org.apache.hc.client5.http.ClientProtocolException; -import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.NameValuePair; @@ -42,7 +40,7 @@ class HttpClientParamsLiveTest { } @Test - void givenStringNameValuePairParams_whenGetRequest_thenResponseOk() throws URISyntaxException, ClientProtocolException, IOException { + void givenStringNameValuePairParams_whenGetRequest_thenResponseOk() throws URISyntaxException, IOException { HttpGet httpGet = new HttpGet("https://postman-echo.com/get"); URI uri = new URIBuilder(httpGet.getUri()).addParameter("param1", "value1") .addParameter("param2", "value2") @@ -59,7 +57,7 @@ class HttpClientParamsLiveTest { } @Test - void givenStringNameValuePairParams_whenPostRequest_thenResponseOk() throws URISyntaxException, ClientProtocolException, IOException { + void givenStringNameValuePairParams_whenPostRequest_thenResponseOk() throws URISyntaxException, IOException { HttpPost httpPost = new HttpPost("https://postman-echo.com/post"); URI uri = new URIBuilder(httpPost.getUri()).addParameter("param1", "value1") .addParameter("param2", "value2") @@ -76,7 +74,7 @@ class HttpClientParamsLiveTest { } @Test - void givenNameValuePairParams_whenGetRequest_thenResponseOk() throws URISyntaxException, ClientProtocolException, IOException { + void givenNameValuePairParams_whenGetRequest_thenResponseOk() throws URISyntaxException, IOException { HttpGet httpGet = new HttpGet("https://postman-echo.com/get"); URI uri = new URIBuilder(httpGet.getUri()).addParameters(nameValuePairs) .build(); @@ -92,7 +90,7 @@ class HttpClientParamsLiveTest { } @Test - void givenNameValuePairsParams_whenPostRequest_thenResponseOk() throws URISyntaxException, ClientProtocolException, IOException { + void givenNameValuePairsParams_whenPostRequest_thenResponseOk() throws URISyntaxException, IOException { HttpPost httpPost = new HttpPost("https://postman-echo.com/post"); URI uri = new URIBuilder(httpPost.getUri()).addParameters(nameValuePairs) .build(); @@ -108,7 +106,7 @@ class HttpClientParamsLiveTest { } @Test - void givenUrlEncodedEntityParams_whenPostRequest_thenResponseOk() throws URISyntaxException, ClientProtocolException, IOException { + void givenUrlEncodedEntityParams_whenPostRequest_thenResponseOk() throws IOException { HttpPost httpPost = new HttpPost("https://postman-echo.com/post"); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, StandardCharsets.UTF_8)); diff --git a/image-compressing/README.md b/image-compressing/README.md index b2556062b8..d90bb53344 100644 --- a/image-compressing/README.md +++ b/image-compressing/README.md @@ -1 +1,4 @@ -This module contains tutorials related to the image compression in Java. \ No newline at end of file +This module contains tutorials related to the image compression in Java. + +## Relevant Articles +- [Lossy and Lossless Image Compression Using Java](https://www.baeldung.com/java-image-compression-lossy-lossless) diff --git a/image-compressing/pom.xml b/image-compressing/pom.xml index 99cdd65647..8e79cdcc2a 100644 --- a/image-compressing/pom.xml +++ b/image-compressing/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 image-compressing diff --git a/image-processing/pom.xml b/image-processing/pom.xml index 2a2b92ca48..5c59a53337 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -91,10 +91,15 @@ webcam-capture ${webcam-capture.version} + + org.openjfx + javafx-graphics + ${javafx-graphics.version} + - 1.3.5 + 1.3.10 1.51h 3.3.2 4.5.1 @@ -105,6 +110,7 @@ 4.2 0.4.11 1.5.5 + 11 \ No newline at end of file diff --git a/jackson-jr/pom.xml b/jackson-jr/pom.xml new file mode 100644 index 0000000000..0dcb62fdae --- /dev/null +++ b/jackson-jr/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + jackson-jr + jackson-jr + pom + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + com.fasterxml.jackson.jr + jackson-jr-all + 2.15.2 + + + com.fasterxml.jackson.jr + jackson-jr-annotation-support + 2.15.2 + + + org.projectlombok + lombok + RELEASE + compile + + + + + \ No newline at end of file diff --git a/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateDeserializer.java b/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateDeserializer.java new file mode 100644 index 0000000000..df977de966 --- /dev/null +++ b/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateDeserializer.java @@ -0,0 +1,22 @@ +package com.baeldung.jacksonjr; + +import com.fasterxml.jackson.jr.ob.api.ValueReader; +import com.fasterxml.jackson.jr.ob.impl.JSONReader; +import com.fasterxml.jackson.jr.private_.JsonParser; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class CustomDateDeserializer extends ValueReader { + private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + public CustomDateDeserializer () { + super(LocalDate.class); + } + + @Override + public Object read (JSONReader jsonReader, JsonParser jsonParser) throws IOException { + return LocalDate.parse(jsonParser.getText(), dtf); + } +} diff --git a/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateSerializer.java b/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateSerializer.java new file mode 100644 index 0000000000..9b2596cd2c --- /dev/null +++ b/jackson-jr/src/main/java/com/baeldung/jacksonjr/CustomDateSerializer.java @@ -0,0 +1,20 @@ +package com.baeldung.jacksonjr; + +import com.fasterxml.jackson.jr.ob.api.ValueWriter; +import com.fasterxml.jackson.jr.ob.impl.JSONWriter; +import com.fasterxml.jackson.jr.private_.JsonGenerator; + +import java.io.IOException; +import java.time.LocalDate; + +public class CustomDateSerializer implements ValueWriter { + @Override + public void writeValue (JSONWriter jsonWriter, JsonGenerator jsonGenerator, Object o) throws IOException { + jsonGenerator.writeString(o.toString()); + } + + @Override + public Class valueType () { + return LocalDate.class; + } +} diff --git a/jackson-jr/src/main/java/com/baeldung/jacksonjr/JacksonJrFeatures.java b/jackson-jr/src/main/java/com/baeldung/jacksonjr/JacksonJrFeatures.java new file mode 100644 index 0000000000..26adbf12d2 --- /dev/null +++ b/jackson-jr/src/main/java/com/baeldung/jacksonjr/JacksonJrFeatures.java @@ -0,0 +1,96 @@ +package com.baeldung.jacksonjr; + +import com.fasterxml.jackson.jr.annotationsupport.JacksonAnnotationExtension; +import com.fasterxml.jackson.jr.ob.JSON; +import com.fasterxml.jackson.jr.ob.JacksonJrExtension; +import com.fasterxml.jackson.jr.ob.api.ExtensionContext; + +import java.io.IOException; +import java.util.LinkedHashMap; + +public class JacksonJrFeatures { + + public static String jsonObject() throws IOException { + return JSON.std + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .asString(new LinkedHashMap() {{ + put("name", "John Doe"); + put("age", 30); + }}); + } + + public static String jsonComposer() throws IOException { + return JSON.std + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .composeString() + .startObject() + .startArrayField("objectArray") + .startObject() + .put("name", "name1") + .put("age", 11) + .end() + .startObject() + .put("name", "name2") + .put("age", 12) + .end() + .end() + .startArrayField("array") + .add(1) + .add(2) + .add(3) + .end() + .startObjectField("object") + .put("name", "name3") + .put("age", 13) + .end() + .put("last", true) + .end() + .finish(); + } + + public static String objectSerialization(Person person) throws IOException { + return JSON.std + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .asString(person); + } + + public static String objectAnnotationSerialization(Person person) throws IOException { + return JSON.builder() + .register(JacksonAnnotationExtension.std) + .build() + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .asString(person); + } + + public static String customObjectSerialization(Person person) throws IOException { + return JSON.builder() + .register(new JacksonJrExtension() { + @Override + protected void register (ExtensionContext extensionContext) { + extensionContext.insertProvider(new MyHandlerProvider()); + } + }) + .build() + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .asString(person); + } + + public static Person objectDeserialization(String json) throws IOException { + return JSON.std + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .beanFrom(Person.class, json); + } + + public static Person customObjectDeserialization(String json) throws IOException { + return JSON.builder() + .register(new JacksonJrExtension() { + @Override + protected void register (ExtensionContext extensionContext) { + extensionContext.insertProvider(new MyHandlerProvider()); + } + }) + .build() + .with(JSON.Feature.PRETTY_PRINT_OUTPUT) + .beanFrom(Person.class, json); + } +} diff --git a/jackson-jr/src/main/java/com/baeldung/jacksonjr/MyHandlerProvider.java b/jackson-jr/src/main/java/com/baeldung/jacksonjr/MyHandlerProvider.java new file mode 100644 index 0000000000..266a09eecc --- /dev/null +++ b/jackson-jr/src/main/java/com/baeldung/jacksonjr/MyHandlerProvider.java @@ -0,0 +1,28 @@ +package com.baeldung.jacksonjr; + +import com.fasterxml.jackson.jr.ob.api.ReaderWriterProvider; +import com.fasterxml.jackson.jr.ob.api.ValueReader; +import com.fasterxml.jackson.jr.ob.api.ValueWriter; +import com.fasterxml.jackson.jr.ob.impl.JSONReader; +import com.fasterxml.jackson.jr.ob.impl.JSONWriter; + +import java.time.LocalDate; + +public class MyHandlerProvider extends ReaderWriterProvider { + + @Override + public ValueWriter findValueWriter (JSONWriter writeContext, Class type) { + if (type == LocalDate.class) { + return new CustomDateSerializer(); + } + return null; + } + + @Override + public ValueReader findValueReader (JSONReader readContext, Class type) { + if (type.equals(LocalDate.class)) { + return new CustomDateDeserializer(); + } + return null; + } +} diff --git a/jackson-jr/src/main/java/com/baeldung/jacksonjr/Person.java b/jackson-jr/src/main/java/com/baeldung/jacksonjr/Person.java new file mode 100644 index 0000000000..8effc64cd9 --- /dev/null +++ b/jackson-jr/src/main/java/com/baeldung/jacksonjr/Person.java @@ -0,0 +1,19 @@ +package com.baeldung.jacksonjr; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Person { + @JsonProperty("person_name") + private String name; + private int age; + private LocalDate birthDate; +} diff --git a/jackson-jr/src/test/java/com/baeldung/jacksonjr/JacksonJrFeaturesUnitTest.java b/jackson-jr/src/test/java/com/baeldung/jacksonjr/JacksonJrFeaturesUnitTest.java new file mode 100644 index 0000000000..db17d2e175 --- /dev/null +++ b/jackson-jr/src/test/java/com/baeldung/jacksonjr/JacksonJrFeaturesUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.jacksonjr; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.*; + +public class JacksonJrFeaturesUnitTest { + + @Test + public void whenSerializingObject_thenReturnJson() throws IOException { + String json = JacksonJrFeatures.jsonObject(); + assertTrue(json.contains("name")); + assertTrue(json.contains("age")); + } + + @Test + public void whenSerializingComposer_thenReturnJson() throws IOException { + String json = JacksonJrFeatures.jsonComposer(); + assertTrue(json.contains("objectArray")); + assertTrue(json.contains("object")); + } + + @Test + public void whenSerializingSimpleObject_thenAnnotationIsNotConsidered() throws IOException { + Person person = new Person("John Doe", 30, null); + String json = JacksonJrFeatures.objectSerialization(person); + assertTrue(json.contains("name")); + assertFalse(json.contains("person_name")); + } + + @Test + public void whenDeserializingJsonObject_thenObjectsAreEqual() throws IOException { + Person person = new Person("John Doe", 30, null); + String json = JacksonJrFeatures.objectSerialization(person); + Person deserializedPerson = JacksonJrFeatures.objectDeserialization(json); + assertEquals(person, deserializedPerson); + } + + @Test + public void whenSerializingWithAnnotations_thenAnnotationIsConsidered() throws IOException { + Person person = new Person("John Doe", 30, null); + String json = JacksonJrFeatures.objectAnnotationSerialization(person); + assertTrue(json.contains("person_name")); + } + + @Test + public void whenSerializingCustomObject_thenLocalDateIsSerializedAsString() throws IOException { + Person person = new Person("John Doe", 30, LocalDate.now()); + String json = JacksonJrFeatures.customObjectSerialization(person); + System.out.println(json); + assertTrue(json.contains("birthDate")); + } + + @Test + public void whenDeserializingCustomObject_thenLocalDateIsDeserialized() throws IOException { + Person person = new Person("John Doe", 30, LocalDate.now()); + String json = JacksonJrFeatures.customObjectSerialization(person); + Person deserializedPerson = JacksonJrFeatures.customObjectDeserialization(json); + assertEquals(person, deserializedPerson); + } +} diff --git a/jackson-modules/jackson-annotations/README.md b/jackson-modules/jackson-annotations/README.md index 8b405ec778..e3cb6e6b7f 100644 --- a/jackson-modules/jackson-annotations/README.md +++ b/jackson-modules/jackson-annotations/README.md @@ -9,3 +9,4 @@ This module contains articles about Jackson annotations. - [Jackson JSON Views](https://www.baeldung.com/jackson-json-view-annotation) - [Deduction-Based Polymorphism in Jackson 2.12](https://www.baeldung.com/jackson-deduction-based-polymorphism) - [@JsonIgnore vs @Transient](https://www.baeldung.com/java-jsonignore-vs-transient) +- [@JsonMerge Annotation in Jackson](https://www.baeldung.com/java-jsonmerge-annotation-jackson) diff --git a/jackson-modules/jackson-core/README.md b/jackson-modules/jackson-core/README.md index 73293b1e84..5706acec0a 100644 --- a/jackson-modules/jackson-core/README.md +++ b/jackson-modules/jackson-core/README.md @@ -16,3 +16,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Get all the Keys in a JSON String Using JsonNode](https://www.baeldung.com/java-jsonnode-get-keys) - [Difference Between asText() and toString() in JsonNode](https://www.baeldung.com/java-jsonnode-astext-vs-tostring) - [Deserialize Generic Type with Jackson](https://www.baeldung.com/java-deserialize-generic-type-with-jackson) +- [Setting Default Values to Null Fields in Jackson Mapping](https://www.baeldung.com/java-jackson-mapping-default-values-null-fields) +- [Removing JSON Elements With Jackson](https://www.baeldung.com/java-jackson-remove-json-elements) diff --git a/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/JsonSetterDefaultValue.java b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/JsonSetterDefaultValue.java new file mode 100644 index 0000000000..5d8c758e86 --- /dev/null +++ b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/JsonSetterDefaultValue.java @@ -0,0 +1,30 @@ +package com.baeldung.jackson.defaultvalues; + +import com.fasterxml.jackson.annotation.JsonSetter; + +public class JsonSetterDefaultValue { + + private String required; + private String optional = "valueIfMissingEntirely"; + + @JsonSetter("optional") + public void setOptional(String optional){ + if(optional == null){ + this.optional = "valueIfNull"; + } + } + + public String getRequired() { + return required; + } + + public String getOptional() { + return optional; + } + + @Override + public String toString() { + return "NonAnnotatedDefaultValue{" + "required='" + required + '\'' + ", optional='" + optional + '\'' + '}'; + } + +} diff --git a/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NonAnnotatedDefaultValue.java b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NonAnnotatedDefaultValue.java new file mode 100644 index 0000000000..54747642ef --- /dev/null +++ b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NonAnnotatedDefaultValue.java @@ -0,0 +1,20 @@ +package com.baeldung.jackson.defaultvalues; + +public class NonAnnotatedDefaultValue { + + private String required; + private String optional = "defaultValue"; + + public String getRequired() { + return required; + } + + public String getOptional() { + return optional; + } + + @Override + public String toString() { + return "NonAnnotatedDefaultValue{" + "required='" + required + '\'' + ", optional='" + optional + '\'' + '}'; + } +} diff --git a/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NullsSkipDefaultValue.java b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NullsSkipDefaultValue.java new file mode 100644 index 0000000000..8dc585ea30 --- /dev/null +++ b/jackson-modules/jackson-core/src/main/java/com/baeldung/jackson/defaultvalues/NullsSkipDefaultValue.java @@ -0,0 +1,27 @@ +package com.baeldung.jackson.defaultvalues; + +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; + +public class NullsSkipDefaultValue { + + private String required; + @JsonSetter(nulls = Nulls.SKIP) + private String optional = "defaultValue"; + + public void setOptional(String optional){} + + public String getRequired() { + return required; + } + + public String getOptional() { + return optional; + } + + @Override + public String toString() { + return "NonAnnotatedDefaultValue{" + "required='" + required + '\'' + ", optional='" + optional + '\'' + '}'; + } + +} diff --git a/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/defaultvalues/DefaultValuesUnitTest.java b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/defaultvalues/DefaultValuesUnitTest.java new file mode 100644 index 0000000000..813cfaae16 --- /dev/null +++ b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/defaultvalues/DefaultValuesUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.jackson.defaultvalues; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class DefaultValuesUnitTest { + + @Test + public void givenAClassWithADefaultValue_whenReadingJsonWithoutOptionalValue_thenExpectDefaultValueInResult() throws JsonProcessingException { + String noOptionalField = "{\"required\": \"value\"}"; + ObjectMapper objectMapper = new ObjectMapper(); + NonAnnotatedDefaultValue createdObject = objectMapper.readValue(noOptionalField, NonAnnotatedDefaultValue.class); + assert(createdObject.getRequired()).equals("value"); + assert(createdObject.getOptional()).equals("defaultValue"); + } + + @Test + public void givenAClassWithAJsonSetter_whenReadingJsonWithNullOptionalValue_thenExpectDefaultValueInResult() throws JsonProcessingException { + String nullOptionalField = "{\"required\": \"value\", \"optional\": null}"; + ObjectMapper objectMapper = new ObjectMapper(); + JsonSetterDefaultValue createdObject = objectMapper.readValue(nullOptionalField, JsonSetterDefaultValue.class); + assert(createdObject.getRequired()).equals("value"); + assert(createdObject.getOptional()).equals("valueIfNull"); + } + + @Test + public void givenAClassWithAJsonSetterNullsSkip_whenReadingJsonWithNullOptionalValue_thenExpectDefaultValueInResult() throws JsonProcessingException { + String nullOptionalField = "{\"required\": \"value\", \"optional\": null}"; + ObjectMapper objectMapper = new ObjectMapper(); + NullsSkipDefaultValue createdObject = objectMapper.readValue(nullOptionalField, NullsSkipDefaultValue.class); + assert(createdObject.getRequired()).equals("value"); + assert(createdObject.getOptional()).equals("defaultValue"); + } + +} diff --git a/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/jsonnode/RemoveJsonElementsUnitTest.java b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/jsonnode/RemoveJsonElementsUnitTest.java new file mode 100644 index 0000000000..73c0a1f925 --- /dev/null +++ b/jackson-modules/jackson-core/src/test/java/com/baeldung/jackson/jsonnode/RemoveJsonElementsUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.jackson.jsonnode; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.jupiter.api.Assertions; +import java.util.Iterator; +import org.junit.Test; + +public class RemoveJsonElementsUnitTest { + @Test + public void given_JsonData_whenUsingJackson_thenRemoveElementByKey() throws JsonProcessingException { + String json = "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}"; + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(json); + ObjectNode object = (ObjectNode) jsonNode; + object.remove("age"); + String updatedJson = objectMapper.writeValueAsString(object); + Assertions.assertEquals("{\"name\":\"John\",\"city\":\"New York\"}", updatedJson); + } + @Test + public void given_JsonData_whenUsingJackson_thenRemoveElementsByCondition() throws JsonProcessingException { + String json = "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}"; + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(json); + Iterator elements = jsonNode.elements(); + while (elements.hasNext()) { + JsonNode element = elements.next(); + if (element.isNumber() && element.asInt() == 30) { + elements.remove(); + } + } + String updatedJson = objectMapper.writeValueAsString(jsonNode); + Assertions.assertEquals("{\"name\":\"John\",\"city\":\"New York\"}", updatedJson); + } + + @Test + public void given_JsonData_whenUsingJackson_thenRemoveElementFromNestedStructure() throws JsonProcessingException { + String json = "{\"name\": \"John\", \"details\": {\"age\": 30, \"city\": \"New York\"}}"; + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode = objectMapper.readTree(json); + JsonNode detailsNode = jsonNode.path("details"); + ((ObjectNode) detailsNode).remove("age"); + String updatedJson = objectMapper.writeValueAsString(jsonNode); + Assertions.assertEquals("{\"name\":\"John\",\"details\":{\"city\":\"New York\"}}", updatedJson); + } +} diff --git a/java-jdi/pom.xml b/java-jdi/pom.xml index dded13896f..aad2f7cfff 100644 --- a/java-jdi/pom.xml +++ b/java-jdi/pom.xml @@ -41,7 +41,6 @@ - 17 17 diff --git a/java-nashorn/README.md b/java-nashorn/README.md new file mode 100644 index 0000000000..b4394fa94b --- /dev/null +++ b/java-nashorn/README.md @@ -0,0 +1,7 @@ +## Language Interop + +This module contains articles about Java interop with other language integrations. + +### Relevant Articles: + +- [Introduction to Nashorn](http://www.baeldung.com/java-nashorn) diff --git a/java-nashorn/pom.xml b/java-nashorn/pom.xml new file mode 100644 index 0000000000..1c1236d77b --- /dev/null +++ b/java-nashorn/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + java-nashorn + 0.0.1-SNAPSHOT + java-nashorn + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + java-nashorn + + + src/main/resources + true + + + src/test/resources + true + + + + + \ No newline at end of file diff --git a/java-nashorn/src/main/java/com/baeldung/language/interop/python/ScriptEngineManagerUtils.java b/java-nashorn/src/main/java/com/baeldung/language/interop/python/ScriptEngineManagerUtils.java new file mode 100644 index 0000000000..7bf07cf598 --- /dev/null +++ b/java-nashorn/src/main/java/com/baeldung/language/interop/python/ScriptEngineManagerUtils.java @@ -0,0 +1,34 @@ +package com.baeldung.language.interop.python; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; + +public class ScriptEngineManagerUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(ScriptEngineManagerUtils.class); + + private ScriptEngineManagerUtils() { + } + + public static void listEngines() { + ScriptEngineManager manager = new ScriptEngineManager(); + List engines = manager.getEngineFactories(); + + for (ScriptEngineFactory engine : engines) { + LOGGER.info("Engine name: {}", engine.getEngineName()); + LOGGER.info("Version: {}", engine.getEngineVersion()); + LOGGER.info("Language: {}", engine.getLanguageName()); + + LOGGER.info("Short Names:"); + for (String names : engine.getNames()) { + LOGGER.info(names); + } + } + } + +} diff --git a/language-interop/src/main/resources/js/bind.js b/java-nashorn/src/main/resources/js/bind.js similarity index 100% rename from language-interop/src/main/resources/js/bind.js rename to java-nashorn/src/main/resources/js/bind.js diff --git a/language-interop/src/main/resources/js/locations.js b/java-nashorn/src/main/resources/js/locations.js similarity index 100% rename from language-interop/src/main/resources/js/locations.js rename to java-nashorn/src/main/resources/js/locations.js diff --git a/language-interop/src/main/resources/js/math_module.js b/java-nashorn/src/main/resources/js/math_module.js similarity index 100% rename from language-interop/src/main/resources/js/math_module.js rename to java-nashorn/src/main/resources/js/math_module.js diff --git a/language-interop/src/main/resources/js/no_such.js b/java-nashorn/src/main/resources/js/no_such.js similarity index 100% rename from language-interop/src/main/resources/js/no_such.js rename to java-nashorn/src/main/resources/js/no_such.js diff --git a/language-interop/src/main/resources/js/script.js b/java-nashorn/src/main/resources/js/script.js similarity index 100% rename from language-interop/src/main/resources/js/script.js rename to java-nashorn/src/main/resources/js/script.js diff --git a/language-interop/src/main/resources/js/trim.js b/java-nashorn/src/main/resources/js/trim.js similarity index 100% rename from language-interop/src/main/resources/js/trim.js rename to java-nashorn/src/main/resources/js/trim.js diff --git a/language-interop/src/main/resources/js/typed_arrays.js b/java-nashorn/src/main/resources/js/typed_arrays.js similarity index 100% rename from language-interop/src/main/resources/js/typed_arrays.js rename to java-nashorn/src/main/resources/js/typed_arrays.js diff --git a/java-nashorn/src/main/resources/logback.xml b/java-nashorn/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-nashorn/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/language-interop/src/test/java/com/baeldung/language/interop/javascript/NashornUnitTest.java b/java-nashorn/src/test/java/com/baeldung/language/interop/javascript/NashornUnitTest.java similarity index 100% rename from language-interop/src/test/java/com/baeldung/language/interop/javascript/NashornUnitTest.java rename to java-nashorn/src/test/java/com/baeldung/language/interop/javascript/NashornUnitTest.java diff --git a/javax-validation-advanced/.gitignore b/javax-validation-advanced/.gitignore deleted file mode 100644 index 8027134ae9..0000000000 --- a/javax-validation-advanced/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.classpath -.project -.settings/ -target/ -bin/ - diff --git a/javax-validation-advanced/README.md b/javax-validation-advanced/README.md deleted file mode 100644 index b3ed669c39..0000000000 --- a/javax-validation-advanced/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Java Bean Validation Examples - -This module contains articles about Bean Validation. - -### Relevant Articles: -- [Object Validation After Deserialization](https://www.baeldung.com/java-object-validation-deserialization) diff --git a/javax-validation-advanced/pom.xml b/javax-validation-advanced/pom.xml deleted file mode 100644 index 7709f37883..0000000000 --- a/javax-validation-advanced/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 4.0.0 - javax-validation-advanced - javax-validation-advanced - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - org.springframework.boot - spring-boot-starter-validation - ${spring.boot.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.databind.version} - - - - - 2.7.5 - 2.14.0 - - - \ No newline at end of file diff --git a/javaxval-2/README.md b/javaxval-2/README.md index 0fd5ce163b..e10629975c 100644 --- a/javaxval-2/README.md +++ b/javaxval-2/README.md @@ -6,4 +6,5 @@ This module contains articles about Bean Validation. - [Method Constraints with Bean Validation 2.0](https://www.baeldung.com/javax-validation-method-constraints) - [Guide to ParameterMessageInterpolator](https://www.baeldung.com/hibernate-parametermessageinterpolator) - [Hibernate Validator Annotation Processor in Depth](https://www.baeldung.com/hibernate-validator-annotation-processor) +- [Object Validation After Deserialization](https://www.baeldung.com/java-object-validation-deserialization) - More articles: [[<-- prev]](../javaxval) \ No newline at end of file diff --git a/javaxval-2/pom.xml b/javaxval-2/pom.xml index 5c311e10f8..f73f23bcb2 100644 --- a/javaxval-2/pom.xml +++ b/javaxval-2/pom.xml @@ -14,26 +14,6 @@ - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - - - org.glassfish - javax.el - ${javax.el.version} - - - org.springframework - spring-context - ${org.springframework.version} - - - org.springframework - spring-test - ${org.springframework.version} - org.springframework.boot spring-boot-starter-validation @@ -45,6 +25,11 @@ ${spring.boot.version} test + + com.fasterxml.jackson.core + jackson-databind + ${jackson.databind.version} + @@ -58,11 +43,8 @@ - 6.2.3.Final - 6.2.0.Final - 3.0.0 - 5.3.21 - 2.7.1 + 3.0.4 + 2.14.0 \ No newline at end of file diff --git a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java similarity index 97% rename from javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java rename to javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java index 3e20ebad6b..f2425b542f 100644 --- a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerModifierWithValidation.java @@ -1,20 +1,20 @@ -package com.baeldung.javaxval.afterdeserialization; - -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.DeserializationConfig; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.deser.BeanDeserializer; -import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; - -public class BeanDeserializerModifierWithValidation extends BeanDeserializerModifier { - - @Override - public JsonDeserializer modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer deserializer) { - if (deserializer instanceof BeanDeserializer) { - return new BeanDeserializerWithValidation((BeanDeserializer) deserializer); - } - - return deserializer; - } - -} +package com.baeldung.javaxval.afterdeserialization; + +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationConfig; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.deser.BeanDeserializer; +import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; + +public class BeanDeserializerModifierWithValidation extends BeanDeserializerModifier { + + @Override + public JsonDeserializer modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer deserializer) { + if (deserializer instanceof BeanDeserializer) { + return new BeanDeserializerWithValidation((BeanDeserializer) deserializer); + } + + return deserializer; + } + +} diff --git a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java similarity index 81% rename from javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java rename to javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java index 332c83010d..178baaac95 100644 --- a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/BeanDeserializerWithValidation.java @@ -1,40 +1,40 @@ -package com.baeldung.javaxval.afterdeserialization; - -import java.io.IOException; -import java.util.Set; - -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.BeanDeserializer; -import com.fasterxml.jackson.databind.deser.BeanDeserializerBase; - -public class BeanDeserializerWithValidation extends BeanDeserializer { - - private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - private static final Validator validator = factory.getValidator(); - - protected BeanDeserializerWithValidation(BeanDeserializerBase src) { - super(src); - } - - @Override - public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - Object instance = super.deserialize(p, ctxt); - validate(instance); - return instance; - } - - public void validate(T t) { - Set> violations = validator.validate(t); - if (!violations.isEmpty()) { - throw new ConstraintViolationException(violations); - } - } - -} +package com.baeldung.javaxval.afterdeserialization; + +import java.io.IOException; +import java.util.Set; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.BeanDeserializer; +import com.fasterxml.jackson.databind.deser.BeanDeserializerBase; + +public class BeanDeserializerWithValidation extends BeanDeserializer { + + private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + private static final Validator validator = factory.getValidator(); + + protected BeanDeserializerWithValidation(BeanDeserializerBase src) { + super(src); + } + + @Override + public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + Object instance = super.deserialize(p, ctxt); + validate(instance); + return instance; + } + + public void validate(T t) { + Set> violations = validator.validate(t); + if (!violations.isEmpty()) { + throw new ConstraintViolationException(violations); + } + } + +} diff --git a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java similarity index 82% rename from javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java rename to javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java index c1923de265..b359f67078 100644 --- a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/Student.java @@ -1,14 +1,14 @@ -package com.baeldung.javaxval.afterdeserialization; - -import javax.validation.constraints.Size; - -public class Student { - - @Size(min = 5, max = 10, message = "Student's name must be between 5 and 10 characters") - private String name; - - public String getName() { - return name; - } - -} +package com.baeldung.javaxval.afterdeserialization; + +import jakarta.validation.constraints.Size; + +public class Student { + + @Size(min = 5, max = 10, message = "Student's name must be between 5 and 10 characters") + private String name; + + public String getName() { + return name; + } + +} diff --git a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java similarity index 97% rename from javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java rename to javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java index e652a43ccb..588493782e 100644 --- a/javax-validation-advanced/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidation.java @@ -1,24 +1,24 @@ -package com.baeldung.javaxval.afterdeserialization; - -import java.io.IOException; -import java.io.InputStream; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; - -public class StudentDeserializerWithValidation { - - public static Student readStudent(InputStream inputStream) throws IOException { - ObjectMapper mapper = getObjectMapperWithValidation(); - return mapper.readValue(inputStream, Student.class); - } - - private static ObjectMapper getObjectMapperWithValidation() { - SimpleModule validationModule = new SimpleModule(); - validationModule.setDeserializerModifier(new BeanDeserializerModifierWithValidation()); - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(validationModule); - return mapper; - } - -} +package com.baeldung.javaxval.afterdeserialization; + +import java.io.IOException; +import java.io.InputStream; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class StudentDeserializerWithValidation { + + public static Student readStudent(InputStream inputStream) throws IOException { + ObjectMapper mapper = getObjectMapperWithValidation(); + return mapper.readValue(inputStream, Student.class); + } + + private static ObjectMapper getObjectMapperWithValidation() { + SimpleModule validationModule = new SimpleModule(); + validationModule.setDeserializerModifier(new BeanDeserializerModifierWithValidation()); + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(validationModule); + return mapper; + } + +} diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java b/javaxval-2/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java index 2d9b1141ec..c6cd443cf2 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java @@ -1,11 +1,13 @@ package com.baeldung.javaxval.hibernate.validator.ap; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; + import java.util.List; import java.util.Optional; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Past; + public class Message { diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/messageinterpolator/Person.java b/javaxval-2/src/main/java/com/baeldung/javaxval/messageinterpolator/Person.java index 387af48c20..df5b959bfe 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/messageinterpolator/Person.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/messageinterpolator/Person.java @@ -1,8 +1,8 @@ package com.baeldung.javaxval.messageinterpolator; -import javax.validation.constraints.Email; -import javax.validation.constraints.Min; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; public class Person { diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java index 6b48046b5c..38da3b46f6 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameterValidator.java @@ -2,10 +2,10 @@ package com.baeldung.javaxval.methodvalidation.constraints; import java.time.LocalDate; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.constraintvalidation.SupportedValidationTarget; -import javax.validation.constraintvalidation.ValidationTarget; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.constraintvalidation.SupportedValidationTarget; +import jakarta.validation.constraintvalidation.ValidationTarget; @SupportedValidationTarget(ValidationTarget.PARAMETERS) public class ConsistentDateParameterValidator implements ConstraintValidator { diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java index 83f551d45f..23c9cc67e6 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ConsistentDateParameters.java @@ -8,8 +8,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; @Constraint(validatedBy = ConsistentDateParameterValidator.class) @Target({ METHOD, CONSTRUCTOR }) diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java index c28cc79004..0a4000e32f 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservation.java @@ -8,8 +8,8 @@ import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; @Constraint(validatedBy = ValidReservationValidator.class) @Target({ METHOD, CONSTRUCTOR }) diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java index 541fc15e9c..699c8309cc 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/constraints/ValidReservationValidator.java @@ -2,8 +2,8 @@ package com.baeldung.javaxval.methodvalidation.constraints; import java.time.LocalDate; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import com.baeldung.javaxval.methodvalidation.model.Reservation; diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Customer.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Customer.java index e0b7fcf917..ba1c1cd341 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Customer.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Customer.java @@ -1,7 +1,7 @@ package com.baeldung.javaxval.methodvalidation.model; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import org.springframework.validation.annotation.Validated; diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Reservation.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Reservation.java index a6d5ab42b1..7b41cfba33 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Reservation.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/Reservation.java @@ -2,8 +2,8 @@ package com.baeldung.javaxval.methodvalidation.model; import java.time.LocalDate; -import javax.validation.Valid; -import javax.validation.constraints.Positive; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Positive; import org.springframework.validation.annotation.Validated; diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/ReservationManagement.java b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/ReservationManagement.java index ec71502119..2170c633cf 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/ReservationManagement.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/methodvalidation/model/ReservationManagement.java @@ -3,11 +3,11 @@ package com.baeldung.javaxval.methodvalidation.model; import java.time.LocalDate; import java.util.List; -import javax.validation.Valid; -import javax.validation.constraints.Future; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/NotNullMethodParameter.java b/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/NotNullMethodParameter.java index 47f0ee69fe..8b950b81ab 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/NotNullMethodParameter.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/NotNullMethodParameter.java @@ -1,9 +1,9 @@ package com.baeldung.javaxval.notnull; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotNull; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.constraints.NotNull; public class NotNullMethodParameter { diff --git a/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/ValidatingComponent.java b/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/ValidatingComponent.java index dc6db0b7b7..eedfeda962 100644 --- a/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/ValidatingComponent.java +++ b/javaxval-2/src/main/java/com/baeldung/javaxval/notnull/ValidatingComponent.java @@ -1,6 +1,6 @@ package com.baeldung.javaxval.notnull; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; diff --git a/javax-validation-advanced/src/test/java/com/baeldung/javaxval/StudentDeserializerWithValidationUnitTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java similarity index 95% rename from javax-validation-advanced/src/test/java/com/baeldung/javaxval/StudentDeserializerWithValidationUnitTest.java rename to javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java index edbe85ecfe..094236e963 100644 --- a/javax-validation-advanced/src/test/java/com/baeldung/javaxval/StudentDeserializerWithValidationUnitTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java @@ -1,51 +1,51 @@ -package com.baeldung.javaxval; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.io.IOException; -import java.io.InputStream; - -import javax.validation.ConstraintViolationException; - -import org.junit.jupiter.api.Test; - -import com.baeldung.javaxval.afterdeserialization.Student; -import com.baeldung.javaxval.afterdeserialization.StudentDeserializerWithValidation; - -public class StudentDeserializerWithValidationUnitTest { - - private final String EXPECTED_ERROR_MESSAGE = "name: Student's name must be between 5 and 10 characters"; - private final String EXPECTED_STUDENT_NAME = "Daniel"; - private final String NAME_TOO_LONG_STUDENT_FILE = "nameTooLongStudent.json"; - private final String NAME_TOO_SHORT_STUDENT_FILE = "nameTooShortStudent.json"; - private final String SUBDIRECTORY = "afterdeserialization/"; - private final String VALID_STUDENT_FILE = "validStudent.json"; - - @Test - void givenValidStudent_WhenReadStudent_ThenReturnStudent() throws IOException { - InputStream inputStream = getInputStream(VALID_STUDENT_FILE); - Student result = StudentDeserializerWithValidation.readStudent(inputStream); - assertEquals(EXPECTED_STUDENT_NAME, result.getName()); - } - - @Test - void givenStudentWithTooShortName_WhenReadStudent_ThenThrows() { - InputStream inputStream = getInputStream(NAME_TOO_SHORT_STUDENT_FILE); - ConstraintViolationException constraintViolationException = assertThrows(ConstraintViolationException.class, () -> StudentDeserializerWithValidation.readStudent(inputStream)); - assertEquals(EXPECTED_ERROR_MESSAGE, constraintViolationException.getMessage()); - } - - @Test - void givenStudentWithTooLongName_WhenReadStudent_ThenThrows() { - InputStream inputStream = getInputStream(NAME_TOO_LONG_STUDENT_FILE); - ConstraintViolationException constraintViolationException = assertThrows(ConstraintViolationException.class, () -> StudentDeserializerWithValidation.readStudent(inputStream)); - assertEquals(EXPECTED_ERROR_MESSAGE, constraintViolationException.getMessage()); - } - - private InputStream getInputStream(String fileName) { - return getClass().getClassLoader() - .getResourceAsStream(SUBDIRECTORY + fileName); - } - -} +package com.baeldung.javaxval; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.io.InputStream; + +import jakarta.validation.ConstraintViolationException; + +import org.junit.jupiter.api.Test; + +import com.baeldung.javaxval.afterdeserialization.Student; +import com.baeldung.javaxval.afterdeserialization.StudentDeserializerWithValidation; + +public class StudentDeserializerWithValidationUnitTest { + + private final String EXPECTED_ERROR_MESSAGE = "name: Student's name must be between 5 and 10 characters"; + private final String EXPECTED_STUDENT_NAME = "Daniel"; + private final String NAME_TOO_LONG_STUDENT_FILE = "nameTooLongStudent.json"; + private final String NAME_TOO_SHORT_STUDENT_FILE = "nameTooShortStudent.json"; + private final String SUBDIRECTORY = "afterdeserialization/"; + private final String VALID_STUDENT_FILE = "validStudent.json"; + + @Test + void givenValidStudent_WhenReadStudent_ThenReturnStudent() throws IOException { + InputStream inputStream = getInputStream(VALID_STUDENT_FILE); + Student result = StudentDeserializerWithValidation.readStudent(inputStream); + assertEquals(EXPECTED_STUDENT_NAME, result.getName()); + } + + @Test + void givenStudentWithTooShortName_WhenReadStudent_ThenThrows() { + InputStream inputStream = getInputStream(NAME_TOO_SHORT_STUDENT_FILE); + ConstraintViolationException constraintViolationException = assertThrows(ConstraintViolationException.class, () -> StudentDeserializerWithValidation.readStudent(inputStream)); + assertEquals(EXPECTED_ERROR_MESSAGE, constraintViolationException.getMessage()); + } + + @Test + void givenStudentWithTooLongName_WhenReadStudent_ThenThrows() { + InputStream inputStream = getInputStream(NAME_TOO_LONG_STUDENT_FILE); + ConstraintViolationException constraintViolationException = assertThrows(ConstraintViolationException.class, () -> StudentDeserializerWithValidation.readStudent(inputStream)); + assertEquals(EXPECTED_ERROR_MESSAGE, constraintViolationException.getMessage()); + } + + private InputStream getInputStream(String fileName) { + return getClass().getClassLoader() + .getResourceAsStream(SUBDIRECTORY + fileName); + } + +} diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java index a60550aca5..99c1a15a04 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/messageinterpolator/ParameterMessageInterpolaterIntegrationTest.java @@ -4,10 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; import org.junit.BeforeClass; diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java index 1a66bf3c59..0159d984fb 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ContainerValidationIntegrationTest.java @@ -3,7 +3,7 @@ package com.baeldung.javaxval.methodvalidation; import java.time.LocalDate; import java.util.List; -import javax.validation.ConstraintViolationException; +import jakarta.validation.ConstraintViolationException; import org.junit.Rule; import org.junit.Test; diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java index 5713e0b10b..fcf04ef086 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/methodvalidation/ValidationIntegrationTest.java @@ -8,10 +8,10 @@ import java.time.LocalDate; import java.util.Collections; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.ValidatorFactory; -import javax.validation.executable.ExecutableValidator; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.ValidatorFactory; +import jakarta.validation.executable.ExecutableValidator; import org.junit.Before; import org.junit.Test; diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/notnull/ValidatingComponentIntegrationTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/notnull/ValidatingComponentIntegrationTest.java index e18ab38a61..92f86005bd 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/notnull/ValidatingComponentIntegrationTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/notnull/ValidatingComponentIntegrationTest.java @@ -6,9 +6,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.ConstraintViolationException; -import javax.validation.constraints.NotNull; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; +import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/javax-validation-advanced/src/test/resources/afterdeserialization/nameTooLongStudent.json b/javaxval-2/src/test/resources/afterdeserialization/nameTooLongStudent.json similarity index 89% rename from javax-validation-advanced/src/test/resources/afterdeserialization/nameTooLongStudent.json rename to javaxval-2/src/test/resources/afterdeserialization/nameTooLongStudent.json index e537ecb25d..486709db60 100644 --- a/javax-validation-advanced/src/test/resources/afterdeserialization/nameTooLongStudent.json +++ b/javaxval-2/src/test/resources/afterdeserialization/nameTooLongStudent.json @@ -1,3 +1,3 @@ -{ - "name": "Constantine" +{ + "name": "Constantine" } \ No newline at end of file diff --git a/javax-validation-advanced/src/test/resources/afterdeserialization/nameTooShortStudent.json b/javaxval-2/src/test/resources/afterdeserialization/nameTooShortStudent.json similarity index 85% rename from javax-validation-advanced/src/test/resources/afterdeserialization/nameTooShortStudent.json rename to javaxval-2/src/test/resources/afterdeserialization/nameTooShortStudent.json index 79ab10cb80..23410153e3 100644 --- a/javax-validation-advanced/src/test/resources/afterdeserialization/nameTooShortStudent.json +++ b/javaxval-2/src/test/resources/afterdeserialization/nameTooShortStudent.json @@ -1,3 +1,3 @@ -{ - "name": "Max" +{ + "name": "Max" } \ No newline at end of file diff --git a/javax-validation-advanced/src/test/resources/afterdeserialization/validStudent.json b/javaxval-2/src/test/resources/afterdeserialization/validStudent.json similarity index 87% rename from javax-validation-advanced/src/test/resources/afterdeserialization/validStudent.json rename to javaxval-2/src/test/resources/afterdeserialization/validStudent.json index 938002ea51..d106f7d7ce 100644 --- a/javax-validation-advanced/src/test/resources/afterdeserialization/validStudent.json +++ b/javaxval-2/src/test/resources/afterdeserialization/validStudent.json @@ -1,3 +1,3 @@ -{ - "name": "Daniel" +{ + "name": "Daniel" } \ No newline at end of file diff --git a/jaxb/README.md b/jaxb/README.md index a471ccd39d..a2be5d9a1e 100644 --- a/jaxb/README.md +++ b/jaxb/README.md @@ -5,3 +5,4 @@ This module contains articles about JAXB. ### Relevant Articles: - [Guide to JAXB](https://www.baeldung.com/jaxb) - [Unmarshalling Dates Using JAXB](https://www.baeldung.com/jaxb-unmarshalling-dates) +- [JAXP vs JAXB: XML Processing APIs Compared](https://www.baeldung.com/java-jaxp-vs-jaxb) diff --git a/jaxb/pom.xml b/jaxb/pom.xml index ac448d2d62..64a01600df 100644 --- a/jaxb/pom.xml +++ b/jaxb/pom.xml @@ -59,7 +59,7 @@ - + diff --git a/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Department.java b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Department.java new file mode 100644 index 0000000000..e83beda29b --- /dev/null +++ b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Department.java @@ -0,0 +1,9 @@ +package com.baeldung.jaxb.jaxpvsjaxb.jaxb; + +import jakarta.xml.bind.annotation.XmlElement; + + +public class Department { + @XmlElement + private String id; +} diff --git a/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Employee.java b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Employee.java new file mode 100644 index 0000000000..a1bb5ff9dd --- /dev/null +++ b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxb/Employee.java @@ -0,0 +1,8 @@ +package com.baeldung.jaxb.jaxpvsjaxb.jaxb; + +import jakarta.xml.bind.annotation.XmlElement; + +public class Employee { + @XmlElement + private String id; +} diff --git a/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxp/JaxpExample.java b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxp/JaxpExample.java new file mode 100644 index 0000000000..57bc64d592 --- /dev/null +++ b/jaxb/src/main/java/com/baeldung/jaxb/jaxpvsjaxb/jaxp/JaxpExample.java @@ -0,0 +1,18 @@ +package com.baeldung.jaxb.jaxpvsjaxb.jaxp; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import org.w3c.dom.Document; + +public class JaxpExample { + public static void main(String[] args) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse("input.xml"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + diff --git a/jhipster-6/pom.xml b/jhipster-6/pom.xml index b3c5e58319..f2406d1bdb 100644 --- a/jhipster-6/pom.xml +++ b/jhipster-6/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 com.baeldung.jhipster jhipster-6 diff --git a/jhipster-modules/jhipster-microservice/pom.xml b/jhipster-modules/jhipster-microservice/pom.xml index ae58ad2203..7c9ea3f15f 100644 --- a/jhipster-modules/jhipster-microservice/pom.xml +++ b/jhipster-modules/jhipster-microservice/pom.xml @@ -1,12 +1,13 @@ - 4.0.0 jhipster-microservice jhipster-microservice pom - + jhipster-modules com.baeldung.jhipster 1.0.0-SNAPSHOT diff --git a/jhipster-modules/jhipster-monolithic/pom.xml b/jhipster-modules/jhipster-monolithic/pom.xml index ac483fdae6..fbcee8f1ff 100644 --- a/jhipster-modules/jhipster-monolithic/pom.xml +++ b/jhipster-modules/jhipster-monolithic/pom.xml @@ -1,9 +1,10 @@ - 4.0.0 jhipster-monolithic war - jhipster-monolithic + jhipster-monolithic JHipster Monolithic Application @@ -87,7 +88,7 @@ io.dropwizard.metrics metrics-annotation - + io.dropwizard.metrics metrics-core @@ -95,15 +96,15 @@ io.dropwizard.metrics metrics-json - + io.dropwizard.metrics metrics-jvm - + io.dropwizard.metrics metrics-servlet - + io.dropwizard.metrics metrics-servlets @@ -315,7 +316,7 @@ - + @@ -329,7 +330,7 @@ - + @@ -547,9 +548,9 @@ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml org.h2.Driver jdbc:h2:file:./target/h2db/db/baeldung - + baeldung - + hibernate:spring:com.baeldung.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy true debug @@ -913,8 +914,8 @@ v6.10.0 4.3.0 - - + + ${project.build.directory}/test-results 0.0.20 diff --git a/jhipster-modules/jhipster-uaa/gateway/pom.xml b/jhipster-modules/jhipster-uaa/gateway/pom.xml index 536b847237..13652575cd 100644 --- a/jhipster-modules/jhipster-uaa/gateway/pom.xml +++ b/jhipster-modules/jhipster-uaa/gateway/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 @@ -852,21 +854,21 @@ pl.project13.maven git-commit-id-plugin ${git-commit-id-plugin.version} - - - - revision - - - - - false - true - - ^git.commit.id.abbrev$ - ^git.commit.id.describe$ - ^git.branch$ - + + + + revision + + + + + false + true + + ^git.commit.id.abbrev$ + ^git.commit.id.describe$ + ^git.branch$ + @@ -1026,9 +1028,9 @@ jdt_apt false - - - + + + 2.0.25 diff --git a/jhipster-modules/jhipster-uaa/pom.xml b/jhipster-modules/jhipster-uaa/pom.xml index b90b59047d..7c60f95e28 100644 --- a/jhipster-modules/jhipster-uaa/pom.xml +++ b/jhipster-modules/jhipster-uaa/pom.xml @@ -1,12 +1,13 @@ - 4.0.0 jhipster-uaa jhipster-uaa pom - + jhipster-modules com.baeldung.jhipster 1.0.0-SNAPSHOT @@ -15,7 +16,7 @@ uaa gateway - quotes - - + quotes + + diff --git a/jhipster-modules/jhipster-uaa/quotes/pom.xml b/jhipster-modules/jhipster-uaa/quotes/pom.xml index d922be10c2..2a3c550071 100644 --- a/jhipster-modules/jhipster-uaa/quotes/pom.xml +++ b/jhipster-modules/jhipster-uaa/quotes/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 @@ -674,21 +676,21 @@ pl.project13.maven git-commit-id-plugin ${git-commit-id-plugin.version} - - - - revision - - - - - false - true - - ^git.commit.id.abbrev$ - ^git.commit.id.describe$ - ^git.branch$ - + + + + revision + + + + + false + true + + ^git.commit.id.abbrev$ + ^git.commit.id.describe$ + ^git.branch$ + @@ -846,9 +848,9 @@ jdt_apt false - - - + + + 2.0.25 diff --git a/jhipster-modules/jhipster-uaa/uaa/pom.xml b/jhipster-modules/jhipster-uaa/uaa/pom.xml index a43da9c366..42802b6040 100644 --- a/jhipster-modules/jhipster-uaa/uaa/pom.xml +++ b/jhipster-modules/jhipster-uaa/uaa/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 jhipster-uaa @@ -673,21 +675,21 @@ pl.project13.maven git-commit-id-plugin ${git-commit-id-plugin.version} - - - - revision - - - - - false - true - - ^git.commit.id.abbrev$ - ^git.commit.id.describe$ - ^git.branch$ - + + + + revision + + + + + false + true + + ^git.commit.id.abbrev$ + ^git.commit.id.describe$ + ^git.branch$ + @@ -847,9 +849,9 @@ jdt_apt false - - - + + + 2.0.25 diff --git a/jhipster-modules/pom.xml b/jhipster-modules/pom.xml index 789666ffb6..1e11d97f40 100644 --- a/jhipster-modules/pom.xml +++ b/jhipster-modules/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 com.baeldung.jhipster @@ -9,8 +10,8 @@ pom - + parent-boot-1 com.baeldung 0.0.1-SNAPSHOT @@ -55,7 +56,7 @@ jhipster-monolithic jhipster-microservice - jhipster-uaa - + jhipster-uaa + diff --git a/jmeter/README.md b/jmeter/README.md index f01fa4eca5..fe6dd2c539 100644 --- a/jmeter/README.md +++ b/jmeter/README.md @@ -56,3 +56,4 @@ Enjoy it :) - [Basic Authentication in JMeter](https://www.baeldung.com/jmeter-basic-auth) - [JMeter: Latency vs. Load Time](https://www.baeldung.com/java-jmeter-latency-vs-load-time) - [How Do I Generate a Dashboard Report in JMeter?](https://www.baeldung.com/jmeter-dashboard-report) +- [Run JMeter .jmx File From the Command Line and Configure the Report File](https://www.baeldung.com/java-jmeter-command-line) diff --git a/json-modules/gson-2/pom.xml b/json-modules/gson-2/pom.xml index aa451bdeed..c3935d5721 100644 --- a/json-modules/gson-2/pom.xml +++ b/json-modules/gson-2/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 gson-2 gson-2 diff --git a/language-interop/README.md b/language-interop/README.md index f4f2fc0816..458f34a119 100644 --- a/language-interop/README.md +++ b/language-interop/README.md @@ -5,4 +5,3 @@ This module contains articles about Java interop with other language integration ### Relevant Articles: - [How to Call Python From Java](https://www.baeldung.com/java-working-with-python) -- [Introduction to Nashorn](http://www.baeldung.com/java-nashorn) diff --git a/language-interop/pom.xml b/language-interop/pom.xml index 57dd8bdd9a..95d1183e8b 100644 --- a/language-interop/pom.xml +++ b/language-interop/pom.xml @@ -41,7 +41,7 @@ - 2.7.2 + 2.7.3b1 1.3 diff --git a/libraries-apache-commons-2/README.md b/libraries-apache-commons-2/README.md new file mode 100644 index 0000000000..76105d6ea4 --- /dev/null +++ b/libraries-apache-commons-2/README.md @@ -0,0 +1,7 @@ +## Apache Commons + +This module contains articles about Apache Commons libraries. + +### Relevant articles +- [Extracting a Tar File in Java](https://www.baeldung.com/java-extract-tar-file) +- More articles: [[<--prev]](../libraries-apache-commons) diff --git a/libraries-apache-commons-2/log4j.properties b/libraries-apache-commons-2/log4j.properties new file mode 100644 index 0000000000..2173c5d96f --- /dev/null +++ b/libraries-apache-commons-2/log4j.properties @@ -0,0 +1 @@ +log4j.rootLogger=INFO, stdout diff --git a/libraries-apache-commons-2/pom.xml b/libraries-apache-commons-2/pom.xml new file mode 100644 index 0000000000..d771aac9ab --- /dev/null +++ b/libraries-apache-commons-2/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + libraries-apache-commons-2 + libraries-apache-commons-2 + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.apache.commons + commons-compress + ${commons-compress.version} + + + org.apache.ant + ant + ${ant.version} + + + org.apache.commons + commons-vfs2 + ${commons-vfs2.version} + + + + + 1.23.0 + 1.10.13 + 2.9.0 + + + \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/Resources.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/Resources.java new file mode 100644 index 0000000000..15e71eb156 --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/Resources.java @@ -0,0 +1,14 @@ +package com.baeldung.commons.untar; + +import java.io.InputStream; + +public interface Resources { + + static InputStream tarFile() { + return Resources.class.getResourceAsStream("/untar/test.tar"); + } + + static InputStream tarGzFile() { + return Resources.class.getResourceAsStream("/untar/test.tar.gz"); + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/TarExtractor.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/TarExtractor.java new file mode 100644 index 0000000000..73a54bba44 --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/TarExtractor.java @@ -0,0 +1,39 @@ +package com.baeldung.commons.untar; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public abstract class TarExtractor { + + private InputStream tarStream; + private boolean gzip; + private Path destination; + + protected TarExtractor(InputStream in, boolean gzip, Path destination) throws IOException { + this.tarStream = in; + this.gzip = gzip; + this.destination = destination; + + Files.createDirectories(destination); + } + + protected TarExtractor(Path tarFile, Path destination) throws IOException { + this(Files.newInputStream(tarFile), tarFile.endsWith("gz"), destination); + } + + public Path getDestination() { + return destination; + } + + public InputStream getTarStream() { + return tarStream; + } + + public boolean isGzip() { + return gzip; + } + + public abstract void untar() throws IOException; +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorAnt.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorAnt.java new file mode 100644 index 0000000000..5bb4d74beb --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorAnt.java @@ -0,0 +1,37 @@ +package com.baeldung.commons.untar.impl; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.zip.GZIPInputStream; + +import org.apache.tools.tar.TarEntry; +import org.apache.tools.tar.TarInputStream; + +import com.baeldung.commons.untar.TarExtractor; + +public class TarExtractorAnt extends TarExtractor { + + public TarExtractorAnt(InputStream in, boolean gzip, Path destination) throws IOException { + super(in, gzip, destination); + } + + @Override + public void untar() throws IOException { + try (TarInputStream tar = new TarInputStream(new BufferedInputStream( // + isGzip() ? new GZIPInputStream(getTarStream()) : getTarStream()))) { + TarEntry entry; + while ((entry = tar.getNextEntry()) != null) { + Path extractTo = getDestination().resolve(entry.getName()); + if (entry.isDirectory()) { + Files.createDirectories(extractTo); + } else { + Files.copy(tar, extractTo, StandardCopyOption.REPLACE_EXISTING); + } + } + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorCommonsCompress.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorCommonsCompress.java new file mode 100644 index 0000000000..4981426c35 --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorCommonsCompress.java @@ -0,0 +1,38 @@ +package com.baeldung.commons.untar.impl; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; + +import com.baeldung.commons.untar.TarExtractor; + +public class TarExtractorCommonsCompress extends TarExtractor { + + public TarExtractorCommonsCompress(InputStream in, boolean gzip, Path destination) throws IOException { + super(in, gzip, destination); + } + + @Override + public void untar() throws IOException { + try (BufferedInputStream inputStream = new BufferedInputStream(getTarStream()); // + TarArchiveInputStream tar = new TarArchiveInputStream( // + isGzip() ? new GzipCompressorInputStream(inputStream) : inputStream)) { + ArchiveEntry entry; + while ((entry = tar.getNextEntry()) != null) { + Path extractTo = getDestination().resolve(entry.getName()); + if (entry.isDirectory()) { + Files.createDirectories(extractTo); + } else { + Files.copy(tar, extractTo, StandardCopyOption.REPLACE_EXISTING); + } + } + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorVfs.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorVfs.java new file mode 100644 index 0000000000..291fcebfb0 --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/untar/impl/TarExtractorVfs.java @@ -0,0 +1,48 @@ +package com.baeldung.commons.untar.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +import org.apache.commons.vfs2.FileContent; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemManager; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.VFS; + +import com.baeldung.commons.untar.TarExtractor; + +public class TarExtractorVfs extends TarExtractor { + + public TarExtractorVfs(InputStream in, boolean gzip, Path destination) throws IOException { + super(in, gzip, destination); + } + + @Override + public void untar() throws IOException { + Path tmpTar = Files.createTempFile("temp", isGzip() ? ".tar.gz" : ".tar"); + Files.copy(getTarStream(), tmpTar, StandardCopyOption.REPLACE_EXISTING); + + FileSystemManager fsManager = VFS.getManager(); + String uri = String.format("%s:file://%s", isGzip() ? "tgz" : "tar", tmpTar); + FileObject tar = fsManager.resolveFile(uri); + + for (FileObject entry : tar) { + Path extractTo = Paths.get(getDestination().toString(), entry.getName() + .getPath()); + + if (entry.isReadable() && entry.getType() == FileType.FILE) { + Files.createDirectories(extractTo.getParent()); + + try (FileContent content = entry.getContent(); InputStream stream = content.getInputStream()) { + Files.copy(stream, extractTo, StandardCopyOption.REPLACE_EXISTING); + } + } + } + + Files.delete(tmpTar); + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/resources/logback.xml b/libraries-apache-commons-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/libraries-apache-commons-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorAntUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorAntUnitTest.java new file mode 100644 index 0000000000..0b39f49884 --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorAntUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.commons.untar; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +import org.junit.Test; + +import com.baeldung.commons.untar.impl.TarExtractorAnt; + +public class TarExtractorAntUnitTest { + + @Test + public void givenTarFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/ant"); + + new TarExtractorAnt(Resources.tarFile(), false, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } + + @Test + public void givenTarGzFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/ant-gz"); + + new TarExtractorAnt(Resources.tarGzFile(), true, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } +} diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorCommonsCompressUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorCommonsCompressUnitTest.java new file mode 100644 index 0000000000..e9c7d701d3 --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorCommonsCompressUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.commons.untar; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +import com.baeldung.commons.untar.impl.TarExtractorCommonsCompress; + +public class TarExtractorCommonsCompressUnitTest { + + @Test + public void givenTarFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/commons-compress"); + + new TarExtractorCommonsCompress(Resources.tarFile(), false, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } + + @Test + public void givenTarGzFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/commons-compress-gz"); + + new TarExtractorCommonsCompress(Resources.tarGzFile(), true, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorVfsUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorVfsUnitTest.java new file mode 100644 index 0000000000..d5e9004732 --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/untar/TarExtractorVfsUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.commons.untar; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + +import org.junit.Test; + +import com.baeldung.commons.untar.impl.TarExtractorVfs; + +public class TarExtractorVfsUnitTest { + + @Test + public void givenTarFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/vfs"); + + new TarExtractorVfs(Resources.tarFile(), false, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } + + @Test + public void givenTarGzFile_whenUntar_thenExtractedToDestination() throws IOException { + Path destination = Paths.get("/tmp/vfs-gz"); + + new TarExtractorVfs(Resources.tarGzFile(), true, destination).untar(); + + try (Stream files = Files.list(destination)) { + assertTrue(files.findFirst() + .isPresent()); + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/test/resources/untar/test.tar b/libraries-apache-commons-2/src/test/resources/untar/test.tar new file mode 100644 index 0000000000..a0c9e8714f Binary files /dev/null and b/libraries-apache-commons-2/src/test/resources/untar/test.tar differ diff --git a/libraries-apache-commons-2/src/test/resources/untar/test.tar.gz b/libraries-apache-commons-2/src/test/resources/untar/test.tar.gz new file mode 100644 index 0000000000..99bc3ec933 Binary files /dev/null and b/libraries-apache-commons-2/src/test/resources/untar/test.tar.gz differ diff --git a/libraries-apache-commons/README.md b/libraries-apache-commons/README.md index aceea3282a..9623ecca2f 100644 --- a/libraries-apache-commons/README.md +++ b/libraries-apache-commons/README.md @@ -13,4 +13,5 @@ This module contains articles about Apache Commons libraries. - [Apache Commons BeanUtils](https://www.baeldung.com/apache-commons-beanutils) - [Histograms with Apache Commons Frequency](https://www.baeldung.com/apache-commons-frequency) - [An Introduction to Apache Commons Lang 3](https://www.baeldung.com/java-commons-lang-3) -- [Differences Between the Java WatchService API and the Apache Commons IO Monitor Library](https://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library) \ No newline at end of file +- [Differences Between the Java WatchService API and the Apache Commons IO Monitor Library](https://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library) +More articles: [[next-->]](../libraries-apache-commons-2) \ No newline at end of file diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml index 655bad2e2b..b9b785cebb 100644 --- a/libraries-data-2/pom.xml +++ b/libraries-data-2/pom.xml @@ -116,6 +116,11 @@ guava ${guava.version} + + io.minio + minio + ${minio.version} + org.awaitility awaitility @@ -177,6 +182,7 @@ 3.0.0 2.8.4 2.1.13 + 8.5.2 - \ No newline at end of file + diff --git a/libraries-data-2/src/main/java/com/baeldung/minio/MinIOService.java b/libraries-data-2/src/main/java/com/baeldung/minio/MinIOService.java new file mode 100644 index 0000000000..f7a8f498be --- /dev/null +++ b/libraries-data-2/src/main/java/com/baeldung/minio/MinIOService.java @@ -0,0 +1,35 @@ +package com.baeldung.minio; + +import io.minio.GetObjectArgs; +import io.minio.MakeBucketArgs; +import io.minio.MinioClient; +import io.minio.UploadObjectArgs; + +public class MinIOService { + private MinioClient minioClient = + MinioClient.builder() + .endpoint("http://127.0.0.1:9000") + .credentials("minioadmin", "minioadmin") + .build(); + + public void doSomething() throws Exception { + minioClient.makeBucket( + MakeBucketArgs + .builder() + .bucket("user2") + .build()); + + minioClient.uploadObject( + UploadObjectArgs + .builder() + .bucket("user2") + .filename("/tmp/Resume.pdf") + .build()); + + minioClient.getObject( + GetObjectArgs.builder() + .bucket("user2") + .object("Resume.pdf") + .build()); + } +} diff --git a/libraries-data-2/src/test/java/com/baeldung/minio/MinIOServiceLiveTest.java b/libraries-data-2/src/test/java/com/baeldung/minio/MinIOServiceLiveTest.java new file mode 100644 index 0000000000..8737e5e7aa --- /dev/null +++ b/libraries-data-2/src/test/java/com/baeldung/minio/MinIOServiceLiveTest.java @@ -0,0 +1,73 @@ +package com.baeldung.minio; + +import io.minio.*; +import org.junit.Before; +import org.junit.Test; + +import java.io.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MinIOServiceLiveTest { + + private MinioClient minioClient; + + private final String BUCKET_NAME = "livetest"; + + private final String OBJECT_NAME = "minio_sample.txt"; + + private final String CONTENTS = "hello"; + + @Before + public void setup() { + minioClient = + MinioClient.builder() + .endpoint("http://127.0.0.1:9000") + .credentials("minioadmin", "minioadmin") + .build(); + } + + @Test + public void givenFile_whenUploadAndRetrive_thenContentsAreCorrect() throws Exception { + + if(!minioClient.bucketExists(BucketExistsArgs + .builder() + .bucket(BUCKET_NAME) + .build())) { + + minioClient.makeBucket(MakeBucketArgs + .builder() + .bucket(BUCKET_NAME) + .build()); + } + + minioClient.putObject(PutObjectArgs + .builder() + .bucket(BUCKET_NAME) + .object(OBJECT_NAME) + .stream(new ByteArrayInputStream(CONTENTS.getBytes()), CONTENTS.length(),-1) + .build()); + + try (InputStream stream = + minioClient.getObject(GetObjectArgs + .builder() + .bucket(BUCKET_NAME) + .object(OBJECT_NAME) + .build())) { + + byte[] obj = new byte[CONTENTS.length()]; + stream.read(obj); + assertEquals(CONTENTS, new String(obj)); + } + catch (IOException e) { + + } + finally { + minioClient.removeObject(RemoveObjectArgs + .builder() + .bucket(BUCKET_NAME) + .object(OBJECT_NAME) + .build()); + } + } +} diff --git a/libraries-http-2/README.md b/libraries-http-2/README.md index 2b94896ab9..f1215a0b11 100644 --- a/libraries-http-2/README.md +++ b/libraries-http-2/README.md @@ -12,5 +12,6 @@ This module contains articles about HTTP libraries. - [Download a Binary File Using OkHttp](https://www.baeldung.com/java-okhttp-download-binary-file) - [Trusting a Self-Signed Certificate in OkHttp](https://www.baeldung.com/okhttp-self-signed-cert) - [Trusting All Certificates in OkHttp](https://www.baeldung.com/okhttp-client-trust-all-certificates) +- [Mock a URL Connection in Java](https://www.baeldung.com/java-simulate-url-connection) - More articles [[<-- prev]](/libraries-http) diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index 77498dd248..fa3b6534db 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -88,25 +88,25 @@ ${mockito.version} test - - org.jmockit - jmockit - ${jmockit.version} - + + org.jmockit + jmockit + ${jmockit.version} + - + - - - maven-surefire-plugin - - - -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar - - - - - + + + maven-surefire-plugin + + + -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar + + + + + 4.9.1 diff --git a/libraries-transform/pom.xml b/libraries-transform/pom.xml index 0dd7ebcfae..f59682622d 100644 --- a/libraries-transform/pom.xml +++ b/libraries-transform/pom.xml @@ -17,7 +17,7 @@ spoon-core ${spoon-core.version} - + diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index da2984442c..6ea491e28b 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -80,7 +80,6 @@ - 2.9.0 2.19.0 diff --git a/lombok-modules/lombok-2/README.md b/lombok-modules/lombok-2/README.md index fcee23fc82..6d3482d800 100644 --- a/lombok-modules/lombok-2/README.md +++ b/lombok-modules/lombok-2/README.md @@ -12,4 +12,5 @@ This module contains articles about Project Lombok. - [Constructor Injection in Spring with Lombok](https://www.baeldung.com/spring-injection-lombok) - [@StandardException Annotation in Lombok](https://www.baeldung.com/lombok-standardexception-annotation) - [Lombok EqualsAndHashCode Annotation](https://www.baeldung.com/java-lombok-equalsandhashcode) +- [Lombok’s @RequiredArgsConstructor Annotation](https://www.baeldung.com/java-lombok-constructor-annotation) - More articles: [[<-- prev]](../lombok) diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalMembers.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalMembers.java new file mode 100644 index 0000000000..9537c0a664 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalMembers.java @@ -0,0 +1,13 @@ +package com.baeldung.lombok.requiredargsconstructor; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ClassWithFinalMembers { + + private final String stringObject; + + public String getStringObject() { + return stringObject; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalNonNullMembers.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalNonNullMembers.java new file mode 100644 index 0000000000..7585afa6c1 --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithFinalNonNullMembers.java @@ -0,0 +1,26 @@ +package com.baeldung.lombok.requiredargsconstructor; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ClassWithFinalNonNullMembers { + + private final String finalStringObject; + @NonNull + private String nonNullStringObject; + + private String nonFinalStringObject; + + public String getFinalStringObject() { + return finalStringObject; + } + + public String getNonNullStringObject() { + return nonNullStringObject; + } + + public String getNonFinalStringObject() { + return nonFinalStringObject; + } +} diff --git a/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithNonFinalMembers.java b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithNonFinalMembers.java new file mode 100644 index 0000000000..7a125a343a --- /dev/null +++ b/lombok-modules/lombok-2/src/main/java/com/baeldung/lombok/requiredargsconstructor/ClassWithNonFinalMembers.java @@ -0,0 +1,13 @@ +package com.baeldung.lombok.requiredargsconstructor; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ClassWithNonFinalMembers { + + private String stringObject; + + public String getStringObject() { + return stringObject; + } +} diff --git a/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/requiredargsconstructor/RequiredArgsConstructorUnitTest.java b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/requiredargsconstructor/RequiredArgsConstructorUnitTest.java new file mode 100644 index 0000000000..a05fe7eb31 --- /dev/null +++ b/lombok-modules/lombok-2/src/test/java/com/baeldung/lombok/requiredargsconstructor/RequiredArgsConstructorUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.lombok.requiredargsconstructor; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class RequiredArgsConstructorUnitTest { + @Test + void whenClassHasFinalMembers_thenGeneratedConstructorHasParameters() { + ClassWithFinalMembers classWithFinalMembers = new ClassWithFinalMembers("dummyString"); + Assertions.assertNotNull(classWithFinalMembers); + Assertions.assertEquals("dummyString", classWithFinalMembers.getStringObject()); + } + + @Test + void whenClassHasNonFinalMembers_thenGeneratedConstructorHasNoParameters() { + ClassWithNonFinalMembers classWithNonFinalMembers = new ClassWithNonFinalMembers(); + Assertions.assertNotNull(classWithNonFinalMembers); + } + + @Test + void whenClassHasFinalAndNonNullMembers_thenGeneratedConstructorHasParameters() { + ClassWithFinalNonNullMembers classWithFinalNonNullMembers = new ClassWithFinalNonNullMembers("finalString", "nonNullString"); + Assertions.assertNotNull(classWithFinalNonNullMembers); + Assertions.assertEquals("finalString", classWithFinalNonNullMembers.getFinalStringObject()); + Assertions.assertEquals("nonNullString", classWithFinalNonNullMembers.getNonNullStringObject()); + Assertions.assertNull(classWithFinalNonNullMembers.getNonFinalStringObject()); + } +} diff --git a/mapstruct/README.md b/mapstruct/README.md index 46a9f8b213..790b4b1a93 100644 --- a/mapstruct/README.md +++ b/mapstruct/README.md @@ -10,3 +10,4 @@ This module contains articles about MapStruct. - [Ignoring Unmapped Properties with MapStruct](https://www.baeldung.com/mapstruct-ignore-unmapped-properties) - [Mapping Collections with MapStruct](https://www.baeldung.com/java-mapstruct-mapping-collections) - [Use Mapper in Another Mapper with Mapstruct and Java](https://www.baeldung.com/java-mapstruct-nested-mapping) +- [Throw Exception for Unexpected Input for Enum With MapStruct](https://www.baeldung.com/java-mapstruct-enum-unexpected-input-exception) diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index 62c9ca5870..7c279acb7b 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -73,7 +73,7 @@ - 1.5.3.Final + 1.5.5.Final 4.3.4.RELEASE 0.2.0 diff --git a/mapstruct/src/main/java/com/baeldung/enums/InputLevel.java b/mapstruct/src/main/java/com/baeldung/enums/InputLevel.java new file mode 100644 index 0000000000..ba7e6735be --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/enums/InputLevel.java @@ -0,0 +1,7 @@ +package com.baeldung.enums; + +enum InputLevel { + + LOW, MEDIUM, HIGH + +} diff --git a/mapstruct/src/main/java/com/baeldung/enums/LevelMapper.java b/mapstruct/src/main/java/com/baeldung/enums/LevelMapper.java new file mode 100644 index 0000000000..d45d98b075 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/enums/LevelMapper.java @@ -0,0 +1,13 @@ +package com.baeldung.enums; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; + +@Mapper +interface LevelMapper { + + @ValueMapping(source = MappingConstants.ANY_REMAINING, target = MappingConstants.THROW_EXCEPTION) + OutputLevel inputLevelToOutputLevel(InputLevel inputLevel); + +} diff --git a/mapstruct/src/main/java/com/baeldung/enums/OutputLevel.java b/mapstruct/src/main/java/com/baeldung/enums/OutputLevel.java new file mode 100644 index 0000000000..c1554ec9b4 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/enums/OutputLevel.java @@ -0,0 +1,7 @@ +package com.baeldung.enums; + +enum OutputLevel { + + LOW, HIGH + +} diff --git a/mapstruct/src/test/java/com/baeldung/enums/LevelMapperUnitTest.java b/mapstruct/src/test/java/com/baeldung/enums/LevelMapperUnitTest.java new file mode 100644 index 0000000000..a933ad7e83 --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/enums/LevelMapperUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.enums; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class LevelMapperUnitTest { + + LevelMapper levelMapper = Mappers.getMapper(LevelMapper.class); + + @Test + void givenHighInputLevel_WhenInputLevelToOutputLevel_ThenHighOutputLevel() { + assertEquals(OutputLevel.HIGH, levelMapper.inputLevelToOutputLevel(InputLevel.HIGH)); + } + + @Test + void givenMediumInputLevel_WhenInputLevelToOutputLevel_ThenThrows() { + assertThrows(IllegalArgumentException.class, () -> levelMapper.inputLevelToOutputLevel(InputLevel.MEDIUM)); + } + + @Test + void givenLowInputLevel_WhenInputLevelToOutputLevel_ThenLowOutputLevel() { + assertEquals(OutputLevel.LOW, levelMapper.inputLevelToOutputLevel(InputLevel.LOW)); + } + +} diff --git a/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml b/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml index 93c5f7591f..5f90b4202f 100644 --- a/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml +++ b/maven-modules/dependency-exclusion/dummy-surefire-junit47/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.apache.maven.surefire - surefire-junit47 + dummy-surefire-junit47 dummy diff --git a/maven-modules/maven-plugins/jaxws/pom.xml b/maven-modules/maven-plugins/jaxws/pom.xml index a7c4740acb..f17d70c182 100644 --- a/maven-modules/maven-plugins/jaxws/pom.xml +++ b/maven-modules/maven-plugins/jaxws/pom.xml @@ -13,9 +13,9 @@ - javax.xml.bind - jaxb-api - 2.3.0 + jakarta.xml.ws + jakarta.xml.ws-api + 4.0.0 org.glassfish.jaxb @@ -44,9 +44,9 @@ - org.codehaus.mojo + com.sun.xml.ws jaxws-maven-plugin - 2.6 + 4.0.1 diff --git a/maven-modules/maven-pom-types/effective-pom.xml b/maven-modules/maven-pom-types/effective-pom.xml index a2f8460809..d8a4578402 100644 --- a/maven-modules/maven-pom-types/effective-pom.xml +++ b/maven-modules/maven-pom-types/effective-pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung maven-pom-types diff --git a/maven-modules/resume-from/README.md b/maven-modules/resume-from/README.md new file mode 100644 index 0000000000..15f6702fbd --- /dev/null +++ b/maven-modules/resume-from/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Starting the Maven Build From the Point Where It Failed](https://www.baeldung.com/maven-resume-failed-build) diff --git a/maven-modules/resume-from/business/pom.xml b/maven-modules/resume-from/business/pom.xml new file mode 100644 index 0000000000..189be12a0f --- /dev/null +++ b/maven-modules/resume-from/business/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + business + 1.0-SNAPSHOT + business + + com.baeldung + resume-from + 1.0-SNAPSHOT + + + + com.baeldung + lib + 1.0-SNAPSHOT + + + + + 11 + 11 + + + + \ No newline at end of file diff --git a/maven-modules/resume-from/business/src/main/java/Main.java b/maven-modules/resume-from/business/src/main/java/Main.java new file mode 100644 index 0000000000..255cde5062 --- /dev/null +++ b/maven-modules/resume-from/business/src/main/java/Main.java @@ -0,0 +1,6 @@ +public class Main { + + public static void main(String[] args) { + System.out.println("Hello world!"); + } +} \ No newline at end of file diff --git a/maven-modules/resume-from/lib/pom.xml b/maven-modules/resume-from/lib/pom.xml new file mode 100644 index 0000000000..1b1dbc2d17 --- /dev/null +++ b/maven-modules/resume-from/lib/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + lib + 1.0-SNAPSHOT + lib + + com.baeldung + resume-from + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/maven-modules/resume-from/pom.xml b/maven-modules/resume-from/pom.xml new file mode 100644 index 0000000000..972395cbf2 --- /dev/null +++ b/maven-modules/resume-from/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + com.baeldung + resume-from + 1.0-SNAPSHOT + resume-from + pom + + business + lib + + + \ No newline at end of file diff --git a/messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java b/messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java index bc5de17537..e4390a95e5 100644 --- a/messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java +++ b/messaging-modules/apache-camel/src/test/java/com/apache/camel/file/processor/FileProcessorIntegrationTest.java @@ -5,6 +5,7 @@ import java.io.File; import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -33,12 +34,18 @@ public class FileProcessorIntegrationTest { file2.createNewFile(); } + @After + public void tearDown() { + cleanFolder(new File(SOURCE_FOLDER)); + cleanFolder(new File(DESTINATION_FOLDER)); + } + private void cleanFolder(File folder) { File[] files = folder.listFiles(); if (files != null) { for (File file : files) { if (file.isFile()) { - file.delete(); + file.deleteOnExit(); } } } diff --git a/messaging-modules/pom.xml b/messaging-modules/pom.xml index 6fd14f7c64..27524637ab 100644 --- a/messaging-modules/pom.xml +++ b/messaging-modules/pom.xml @@ -22,7 +22,7 @@ spring-amqp spring-apache-camel spring-jms - postgres-notify + postgres-notify \ No newline at end of file diff --git a/messaging-modules/postgres-notify/pom.xml b/messaging-modules/postgres-notify/pom.xml index 174d66b7f5..876519f40c 100644 --- a/messaging-modules/postgres-notify/pom.xml +++ b/messaging-modules/postgres-notify/pom.xml @@ -42,37 +42,36 @@ lombok true - + + + 1.8 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + - - 1.8 - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - instance1 - - - - org.springframework.boot - spring-boot-maven-plugin - - -Dserver.port=8081 - - - - - - - + + + instance1 + + + + org.springframework.boot + spring-boot-maven-plugin + + -Dserver.port=8081 + + + + + + + \ No newline at end of file diff --git a/messaging-modules/rabbitmq/pom.xml b/messaging-modules/rabbitmq/pom.xml index 69476ba31b..2add4b8d35 100644 --- a/messaging-modules/rabbitmq/pom.xml +++ b/messaging-modules/rabbitmq/pom.xml @@ -13,7 +13,6 @@ 0.0.1-SNAPSHOT - diff --git a/metrics/pom.xml b/metrics/pom.xml index d3731242c4..40a1d95d0c 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -16,44 +16,44 @@ io.dropwizard.metrics metrics-core - ${dep.ver.metrics} + ${dropwizard.metrics.version} io.dropwizard.metrics metrics-healthchecks - ${dep.ver.metrics} + ${dropwizard.metrics.version} io.dropwizard.metrics metrics-servlets - ${dep.ver.metrics} + ${dropwizard.metrics.version} io.dropwizard.metrics metrics-servlet - ${dep.ver.metrics} + ${dropwizard.metrics.version} javax.servlet javax.servlet-api - ${dep.ver.servlet} + ${javax.servlet-api.version} com.netflix.servo servo-core - ${netflix.servo.ver} + ${netflix.servo.version} test com.netflix.servo servo-atlas - ${netflix.servo.ver} + ${netflix.servo.version} test io.micrometer micrometer-registry-atlas - ${micrometer.ver} + ${micrometer-registry-atlas.version} org.springframework.boot @@ -73,7 +73,7 @@ io.astefanutti.metrics.aspectj metrics-aspectj-deps - ${metrics-aspectj.version} + ${metrics-aspectj-deps.version} com.netflix.spectator @@ -83,14 +83,12 @@ - 3.1.2 - 3.1.0 - 0.12.17 - 1.7.1 - - 2.0.7.RELEASE - 1.1.0 - 1.0.11 + 4.2.17 + 0.13.2 + 1.11.0 + 3.1.0 + 1.2.0 + 1.5.4 \ No newline at end of file diff --git a/microservices-modules/microprofile/pom.xml b/microservices-modules/microprofile/pom.xml index 24803cb4a4..b2ce768748 100644 --- a/microservices-modules/microprofile/pom.xml +++ b/microservices-modules/microprofile/pom.xml @@ -83,9 +83,9 @@ library ${project.build.directory}/${app.name}-service.jar runnable - 1.2 + 6.0 2.1.2 - 17.0.0.4 + 23.0.0.5 \ No newline at end of file diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java index f5eccf969e..9039cf0234 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/LibraryApplication.java @@ -1,8 +1,8 @@ package com.baeldung.microprofile; -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; -@ApplicationPath("/library") +@ApplicationPath("library") public class LibraryApplication extends Application { } diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java index f7d0bfc5f7..a8a340d1f0 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookListMessageBodyWriter.java @@ -3,15 +3,15 @@ package com.baeldung.microprofile.providers; import com.baeldung.microprofile.model.Book; import com.baeldung.microprofile.util.BookMapper; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonWriter; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonWriter; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.Provider; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java index 26ce4c1b64..3fe6a4a1e4 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyReader.java @@ -3,12 +3,12 @@ package com.baeldung.microprofile.providers; import com.baeldung.microprofile.model.Book; import com.baeldung.microprofile.util.BookMapper; -import javax.ws.rs.Consumes; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.Provider; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyReader; +import jakarta.ws.rs.ext.Provider; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java index 9bc6e89958..3d531c370c 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/providers/BookMessageBodyWriter.java @@ -2,16 +2,16 @@ package com.baeldung.microprofile.providers; import com.baeldung.microprofile.model.Book; import com.baeldung.microprofile.util.BookMapper; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonWriter; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.Provider; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonWriter; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -47,7 +47,8 @@ public class BookMessageBodyWriter implements MessageBodyWriter { * @throws WebApplicationException */ @Override - public void writeTo(Book book, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { + public void writeTo(Book book, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, + MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { JsonWriter jsonWriter = Json.createWriter(entityStream); JsonObject jsonObject = BookMapper.map(book); jsonWriter.writeObject(jsonObject); diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java index 924cf0ce71..d46506af00 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/repo/BookManager.java @@ -1,8 +1,8 @@ package com.baeldung.microprofile.repo; import com.baeldung.microprofile.model.Book; +import jakarta.enterprise.context.ApplicationScoped; -import javax.enterprise.context.ApplicationScoped; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java index 861b172299..5eb7439678 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/util/BookMapper.java @@ -1,8 +1,8 @@ package com.baeldung.microprofile.util; import com.baeldung.microprofile.model.Book; +import jakarta.json.*; -import javax.json.*; import java.io.InputStream; import java.util.List; diff --git a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java index 13143a5644..f5dac2f1b7 100644 --- a/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java +++ b/microservices-modules/microprofile/src/main/java/com/baeldung/microprofile/web/BookEndpoint.java @@ -2,13 +2,12 @@ package com.baeldung.microprofile.web; import com.baeldung.microprofile.model.Book; import com.baeldung.microprofile.repo.BookManager; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriBuilder; +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.UriBuilder; @Path("books") @RequestScoped diff --git a/microservices-modules/microprofile/src/main/liberty/config/server.xml b/microservices-modules/microprofile/src/main/liberty/config/server.xml index 2b855bee05..084c70a27b 100644 --- a/microservices-modules/microprofile/src/main/liberty/config/server.xml +++ b/microservices-modules/microprofile/src/main/liberty/config/server.xml @@ -1,8 +1,8 @@ - jaxrs-2.0 - cdi-1.2 - jsonp-1.0 + jakartaee-10.0 + jsonp-2.1 + cdi-4.0 diff --git a/microservices-modules/rest-express/pom.xml b/microservices-modules/rest-express/pom.xml index e92607aec7..da697fdc56 100644 --- a/microservices-modules/rest-express/pom.xml +++ b/microservices-modules/rest-express/pom.xml @@ -24,7 +24,6 @@ rest-express jar - com.strategicgains diff --git a/netflix-modules/mantis/pom.xml b/netflix-modules/mantis/pom.xml index 50d9e61d9e..351f079481 100644 --- a/netflix-modules/mantis/pom.xml +++ b/netflix-modules/mantis/pom.xml @@ -54,6 +54,11 @@ reactor-netty test + + com.netflix.spectator + spectator-api + ${spectator-api.version} + @@ -64,8 +69,9 @@ - 1.2.63 + 2.0.42 0.4.2 + 1.6.5 \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index fd3cd734c6..d03eb3def6 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -24,7 +24,7 @@ - 5.3.25 + 5.3.28 5.7.3 1.5.10.RELEASE diff --git a/parent-spring-6/pom.xml b/parent-spring-6/pom.xml index d91a12bcc5..77afe2072a 100644 --- a/parent-spring-6/pom.xml +++ b/parent-spring-6/pom.xml @@ -35,7 +35,7 @@ - 6.0.8 + 6.0.10 diff --git a/patterns-modules/design-patterns-behavioral-2/README.md b/patterns-modules/design-patterns-behavioral-2/README.md index db4dd8d719..2afa7b9eb6 100644 --- a/patterns-modules/design-patterns-behavioral-2/README.md +++ b/patterns-modules/design-patterns-behavioral-2/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Memento Design Pattern in Java](https://www.baeldung.com/java-memento-design-pattern) - [Difference Between Fluent Interface and Builder Pattern in Java](https://www.baeldung.com/java-fluent-interface-vs-builder-pattern) +- [Smart Batching in Java](https://www.baeldung.com/java-smart-batching) diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/BatchingApp.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/BatchingApp.java new file mode 100644 index 0000000000..8f95d5cbee --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/BatchingApp.java @@ -0,0 +1,72 @@ +package com.baeldung.smartbatching; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; + +/** + * @author KPentaris + * @date 07/06/2023 + * @project design-patterns-behavioral-2 + */ +public class BatchingApp { + + static void simpleProcessing() throws Exception { + final Path testPath = Paths.get("./testio.txt"); + testPath.toFile().createNewFile(); + ScheduledExecutorService executorService = Executors.newScheduledThreadPool(100); + Set futures = new HashSet<>(); + for (int i = 0; i < 50000; i++) { + futures.add(executorService.submit(() -> { + try { + Files.write(testPath, Collections.singleton(Thread.currentThread().getName()), StandardOpenOption.APPEND); + } catch (IOException e) { + e.printStackTrace(); + } + })); + } + long start = System.currentTimeMillis(); + for (Future future : futures) { + future.get(); + } + System.out.println("Time: " + (System.currentTimeMillis() - start)); + executorService.shutdown(); + } + + static void batchedProcessing() throws Exception { + final Path testPath = Paths.get("./testio.txt"); + testPath.toFile().createNewFile(); + SmartBatcher batcher = new SmartBatcher(10, strings -> { + List content = new ArrayList<>(strings); + content.add("-----Batch Operation-----"); + try { + Files.write(testPath, content, StandardOpenOption.APPEND); + } catch (IOException e) { + e.printStackTrace(); + } + }); + for (int i = 0; i < 50000; i++) { + batcher.submit(Thread.currentThread().getName() + "-1"); + } + long start = System.currentTimeMillis(); + while (!batcher.finished()) { + Thread.sleep(10); + } + System.out.println("Time: " + (System.currentTimeMillis() - start)); + } + + public static void main(String[] args) throws Exception { +// simpleProcessing(); + batchedProcessing(); + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/MicroBatcher.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/MicroBatcher.java new file mode 100644 index 0000000000..b6d171246a --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/MicroBatcher.java @@ -0,0 +1,59 @@ +package com.baeldung.smartbatching; + +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; + +/** + * @author KPentaris + * @date 07/06/2023 + * @project design-patterns-behavioral-2 + */ +public class MicroBatcher { + Queue tasksQueue = new ConcurrentLinkedQueue<>(); + Thread batchThread; + int executionThreshold; + int timeoutThreshold; + boolean working = false; + + MicroBatcher(int executionThreshold, int timeoutThreshold, Consumer> executionLogic) { + batchThread = new Thread(batchHandling(executionLogic)); + batchThread.setDaemon(true); + batchThread.start(); + this.executionThreshold = executionThreshold; + this.timeoutThreshold = timeoutThreshold; + } + + void submit(String task) { + tasksQueue.add(task); + } + + Runnable batchHandling(Consumer> executionLogic) { + return () -> { + while (!batchThread.isInterrupted()) { + long startTime = System.currentTimeMillis(); + while (tasksQueue.size() < executionThreshold && (System.currentTimeMillis() - startTime) < timeoutThreshold) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + return; // exit the external loop + } + } + List tasks = new ArrayList<>(executionThreshold); + while (tasksQueue.size() > 0 && tasks.size() < executionThreshold) { + tasks.add(tasksQueue.poll()); + } + working = true; + executionLogic.accept(tasks); + working = false; + } + }; + } + + boolean finished() { + return tasksQueue.isEmpty() && !working; + } + +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/SmartBatcher.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/SmartBatcher.java new file mode 100644 index 0000000000..d4aab8e986 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/smartbatching/SmartBatcher.java @@ -0,0 +1,52 @@ +package com.baeldung.smartbatching; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; + +/** + * @author KPentaris + * @date 07/06/2023 + * @project design-patterns-behavioral-2 + */ +public class SmartBatcher { + BlockingQueue tasksQueue = new LinkedBlockingQueue<>(); + Thread batchThread; + int executionThreshold; + boolean working = false; + + SmartBatcher(int executionThreshold, Consumer> executionLogic) { + batchThread = new Thread(batchHandling(executionLogic)); + batchThread.setDaemon(true); + batchThread.start(); + this.executionThreshold = executionThreshold; + } + + void submit(String task) { + tasksQueue.add(task); + } + + Runnable batchHandling(Consumer> executionLogic) { + return () -> { + while (!batchThread.isInterrupted()) { + List tasks = new ArrayList<>(executionThreshold); + while (tasksQueue.drainTo(tasks, executionThreshold) == 0) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + return; // exit the external loop + } + } + working = true; + executionLogic.accept(tasks); + working = false; + } + }; + } + + boolean finished() { + return tasksQueue.isEmpty() && !working; + } +} diff --git a/pdf/input.docx b/pdf/input.docx new file mode 100644 index 0000000000..b6b2b09f79 Binary files /dev/null and b/pdf/input.docx differ diff --git a/pdf/output.pdf b/pdf/output.pdf new file mode 100644 index 0000000000..ebbe80989e Binary files /dev/null and b/pdf/output.pdf differ diff --git a/pdf/src/main/java/com/baeldung/pdf/DocxToPDFExample.java b/pdf/src/main/java/com/baeldung/pdf/DocxToPDFExample.java new file mode 100644 index 0000000000..1df5e7eef2 --- /dev/null +++ b/pdf/src/main/java/com/baeldung/pdf/DocxToPDFExample.java @@ -0,0 +1,35 @@ +package com.baeldung.pdf; + +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Paragraph; +import com.itextpdf.text.pdf.PdfWriter; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +public class DocxToPDFExample { + + public static void main(String[] args) throws IOException, DocumentException { + InputStream docxInputStream = new FileInputStream("input.docx"); + try (XWPFDocument document = new XWPFDocument(docxInputStream); + OutputStream pdfOutputStream = new FileOutputStream("output.pdf");) { + Document pdfDocument = new Document(); + PdfWriter.getInstance(pdfDocument, pdfOutputStream); + pdfDocument.open(); + + List paragraphs = document.getParagraphs(); + for (XWPFParagraph paragraph : paragraphs) { + pdfDocument.add(new Paragraph(paragraph.getText())); + } + pdfDocument.close(); + } + } +} diff --git a/persistence-modules/neo4j/README.md b/persistence-modules/neo4j/README.md new file mode 100644 index 0000000000..c40fdad388 --- /dev/null +++ b/persistence-modules/neo4j/README.md @@ -0,0 +1,13 @@ +### Relevant Articles: +- [A Guide to Neo4J with Java](https://www.baeldung.com/java-neo4j) + +### Build the Project with Tests Running +``` +mvn clean install +``` + +### Run Tests Directly +``` +mvn test +``` + diff --git a/persistence-modules/neo4j/pom.xml b/persistence-modules/neo4j/pom.xml new file mode 100644 index 0000000000..91a488637a --- /dev/null +++ b/persistence-modules/neo4j/pom.xml @@ -0,0 +1,117 @@ + + + 4.0.0 + neo4j + 1.0 + neo4j + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + org.neo4j + neo4j + ${neo4j.version} + + + org.neo4j + neo4j-ogm-core + ${neo4j-ogm-core.version} + + + org.neo4j + neo4j-ogm-embedded-driver + ${neo4j-ogm-embedded.version} + + + org.neo4j + neo4j-ogm-bolt-driver + ${neo4j-ogm-bolt-driver.version} + + + org.neo4j.driver + neo4j-java-driver + ${neo4j-java-driver.version} + + + org.neo4j + neo4j-jdbc-driver + ${neo4j-jdbc.version} + runtime + + + com.voodoodyne.jackson.jsog + jackson-jsog + ${jackson-jsog.version} + compile + + + org.neo4j + neo4j-kernel + ${neo4j.version} + test-jar + + + org.neo4j.app + neo4j-server + ${neo4j.version} + test-jar + + + commons-logging + commons-logging + + + + + org.neo4j + neo4j-ogm-test + ${neo4j-ogm.version} + test + + + org.neo4j.test + neo4j-harness + ${neo4j.version} + test + + + org.testcontainers + neo4j + ${testcontainers.version} + test + + + org.jetbrains + annotations + + + org.apache.commons + commons-compress + + + javax.xml.bind + jaxb-api + + + + + + + 5.6.0 + 5.8.0 + 1.1.2 + 3.1.22 + 4.0.5 + 3.2.39 + 4.0.9 + 4.0.5 + + + \ No newline at end of file diff --git a/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Car.java b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Car.java new file mode 100644 index 0000000000..d396cc94e7 --- /dev/null +++ b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Car.java @@ -0,0 +1,50 @@ +package com.baeldung.neo4j.domain; + +import static org.neo4j.ogm.annotation.Relationship.Direction.INCOMING; + +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Relationship; + +@NodeEntity +public class Car { + @Id @GeneratedValue + private Long id; + + private String make; + + @Relationship(direction = INCOMING) + private Company company; + + public Car(String make, String model) { + this.make = make; + this.model = model; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + private String model; +} diff --git a/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Company.java b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Company.java new file mode 100644 index 0000000000..7749db9d74 --- /dev/null +++ b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Company.java @@ -0,0 +1,42 @@ +package com.baeldung.neo4j.domain; + +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Relationship; + +@NodeEntity +public class Company { + private Long id; + + private String name; + + @Relationship(type="owns") + private Car car; + + public Company(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Car getCar() { + return car; + } + + public void setCar(Car car) { + this.car = car; + } +} diff --git a/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Movie.java b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Movie.java new file mode 100644 index 0000000000..c6a0a9a529 --- /dev/null +++ b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Movie.java @@ -0,0 +1,66 @@ +package com.baeldung.neo4j.domain; + +import static org.neo4j.ogm.annotation.Relationship.Direction.INCOMING; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.voodoodyne.jackson.jsog.JSOGGenerator; + +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Relationship; + +import java.util.Collection; +import java.util.List; + +@JsonIdentityInfo(generator = JSOGGenerator.class) + +@NodeEntity +public class Movie { + @Id @GeneratedValue + Long id; + + private String title; + + private int released; + private String tagline; + + @Relationship(type = "ACTED_IN", direction = INCOMING) + private List roles; + + public Movie() { + } + + public String getTitle() { + return title; + } + + public int getReleased() { + return released; + } + + public String getTagline() { + return tagline; + } + + public Collection getRoles() { + return roles; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setReleased(int released) { + this.released = released; + } + + public void setTagline(String tagline) { + this.tagline = tagline; + } + + public void setRoles(List roles) { + this.roles = roles; + } + +} diff --git a/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Person.java b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Person.java new file mode 100644 index 0000000000..a9491ee876 --- /dev/null +++ b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Person.java @@ -0,0 +1,52 @@ +package com.baeldung.neo4j.domain; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.voodoodyne.jackson.jsog.JSOGGenerator; + +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; +import org.neo4j.ogm.annotation.NodeEntity; +import org.neo4j.ogm.annotation.Relationship; + +import java.util.List; + +@JsonIdentityInfo(generator = JSOGGenerator.class) +@NodeEntity +public class Person { + @Id @GeneratedValue + Long id; + + private String name; + private int born; + + @Relationship(type = "ACTED_IN") + private List movies; + + public Person() { + } + + public String getName() { + return name; + } + + public int getBorn() { + return born; + } + + public List getMovies() { + return movies; + } + + public void setName(String name) { + this.name = name; + } + + public void setBorn(int born) { + this.born = born; + } + + public void setMovies(List movies) { + this.movies = movies; + } + +} diff --git a/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Role.java b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Role.java new file mode 100644 index 0000000000..0c91e67f0c --- /dev/null +++ b/persistence-modules/neo4j/src/main/java/com/baeldung/neo4j/domain/Role.java @@ -0,0 +1,50 @@ +package com.baeldung.neo4j.domain; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.voodoodyne.jackson.jsog.JSOGGenerator; +import org.neo4j.ogm.annotation.EndNode; +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; +import org.neo4j.ogm.annotation.RelationshipEntity; +import org.neo4j.ogm.annotation.StartNode; + +import java.util.Collection; + +@JsonIdentityInfo(generator = JSOGGenerator.class) +@RelationshipEntity(type = "ACTED_IN") +public class Role { + @Id @GeneratedValue + Long id; + private Collection roles; + @StartNode + private Person person; + @EndNode + private Movie movie; + + public Role() { + } + + public Collection getRoles() { + return roles; + } + + public Person getPerson() { + return person; + } + + public Movie getMovie() { + return movie; + } + + public void setRoles(Collection roles) { + this.roles = roles; + } + + public void setPerson(Person person) { + this.person = person; + } + + public void setMovie(Movie movie) { + this.movie = movie; + } +} diff --git a/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java new file mode 100644 index 0000000000..2232c68e8e --- /dev/null +++ b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java @@ -0,0 +1,79 @@ +package com.baeldung.neo4j; + +import static com.baeldung.neo4j.TestContainersTestBase.DEFAULT_PASSWORD; +import static com.baeldung.neo4j.TestContainersTestBase.getNewBoltConnection; +import static com.baeldung.neo4j.TestContainersTestBase.neo4jServer; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.neo4j.driver.Driver; +import org.neo4j.driver.Result; +import org.neo4j.driver.Session; + + +/** + * To run this test you will need to have an instance of the docker running on your machine (Docker desktop - for Windows and Docker instance for linux) + * After your docker instance is up run this test + */ +class Neo4JServerLiveTest { + + private static Session session; + private static Driver driver; + + @BeforeAll + public static void setup() { + driver = getNewBoltConnection(); + } + + @AfterAll + public static void tearDown() { + driver.close(); + } + + @Test + void standAloneDriver() { + session = driver.session(); + session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + + "RETURN baeldung, tesla"); + + Result result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" + + "WHERE car.make='tesla' and car.model='modelX'" + + "RETURN company.name"); + + assertTrue(result.hasNext()); + assertEquals("Baeldung", result.next().get("company.name").asString()); + + session.close(); + } + + @Test + void standAloneJdbc() throws Exception { + String uri = "jdbc:neo4j:" + neo4jServer.getBoltUrl() + "/?user=neo4j,password=" + DEFAULT_PASSWORD + ",scheme=basic"; + Connection con = DriverManager.getConnection(uri); + + // Querying + try (Statement stmt = con.createStatement()) { + stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + + "RETURN baeldung, tesla"); + + ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" + + "WHERE car.make='tesla' and car.model='modelX'" + + "RETURN company.name"); + + while (rs.next()) { + assertEquals("Baeldung", rs.getString("company.name")); + } + } + con.close(); + } +} diff --git a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java similarity index 63% rename from persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java rename to persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java index 1ff01b93a1..8591dd3a8d 100644 --- a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java +++ b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java @@ -1,7 +1,10 @@ package com.baeldung.neo4j; +import static org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME; + import java.io.File; +import java.time.Duration; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -10,101 +13,111 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.neo4j.configuration.GraphDatabaseSettings; +import org.neo4j.dbms.api.DatabaseManagementService; +import org.neo4j.dbms.api.DatabaseManagementServiceBuilder; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.NotFoundException; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Result; -import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import org.neo4j.graphdb.Transaction; +/** + * To run this test you will need to have an instance of the docker running on your machine (Docker desktop - for Windows and Docker instance for linux) + * After your docker instance is up run this test + */ public class Neo4jLiveTest { private static GraphDatabaseService graphDb; + private static Transaction transaction; + private static DatabaseManagementService managementService; @Before public void setUp() { - GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory(); - graphDb = graphDbFactory.newEmbeddedDatabase(new File("data/cars")); + managementService = new DatabaseManagementServiceBuilder(new File("data/cars").toPath()) + .setConfig( GraphDatabaseSettings.transaction_timeout, Duration.ofSeconds( 60 ) ) + .setConfig( GraphDatabaseSettings.preallocate_logical_logs, false ).build(); + graphDb = managementService.database( DEFAULT_DATABASE_NAME ); } @After public void tearDown() { - graphDb.shutdown(); + managementService.shutdown(); } @Test public void testPersonCar() { - graphDb.beginTx(); - Node car = graphDb.createNode(Label.label("Car")); + transaction = graphDb.beginTx(); + Node car = transaction.createNode(Label.label("Car")); car.setProperty("make", "tesla"); car.setProperty("model", "model3"); - Node owner = graphDb.createNode(Label.label("Person")); + Node owner = transaction.createNode(Label.label("Person")); owner.setProperty("firstName", "baeldung"); owner.setProperty("lastName", "baeldung"); owner.createRelationshipTo(car, RelationshipType.withName("owner")); - Result result = graphDb.execute("MATCH (c:Car) <-[owner]- (p:Person) " + + Result result = transaction.execute("MATCH (c:Car) <-[owner]- (p:Person) " + "WHERE c.make = 'tesla'" + "RETURN p.firstName, p.lastName"); Map firstResult = result.next(); + Assert.assertEquals("baeldung", firstResult.get("p.firstName")); } @Test public void testCreateNode() { - - graphDb.beginTx(); - - Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" + + transaction = graphDb.beginTx(); + Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" + "RETURN baeldung"); Map firstResult = result.next(); Node firstNode = (Node) firstResult.get("baeldung"); + Assert.assertEquals(firstNode.getProperty("name"), "Baeldung"); } @Test public void testCreateNodeAndLink() { - graphDb.beginTx(); - - Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + transaction = graphDb.beginTx(); + Result result = transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla"); Map firstResult = result.next(); + Assert.assertTrue(firstResult.containsKey("baeldung")); Assert.assertTrue(firstResult.containsKey("tesla")); } @Test public void testFindAndReturn() { - graphDb.beginTx(); - - graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + transaction = graphDb.beginTx(); + transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla"); - Result result = graphDb.execute("MATCH (company:Company)-[:owns]-> (car:Car)" + + Result result = transaction.execute("MATCH (company:Company)-[:owns]-> (car:Car)" + "WHERE car.make='tesla' and car.model='modelX'" + "RETURN company.name"); Map firstResult = result.next(); + Assert.assertEquals(firstResult.get("company.name"), "Baeldung"); } @Test public void testUpdate() { - graphDb.beginTx(); - - graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + transaction = graphDb.beginTx(); + transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla"); - Result result = graphDb.execute("MATCH (car:Car)" + + Result result = transaction.execute("MATCH (car:Car)" + "WHERE car.make='tesla'" + " SET car.milage=120" + " SET car :Car:Electro" + @@ -127,17 +140,16 @@ public class Neo4jLiveTest { @Test public void testDelete() { - graphDb.beginTx(); - - graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + + transaction = graphDb.beginTx(); + transaction.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + "RETURN baeldung, tesla"); - graphDb.execute("MATCH (company:Company)" + + transaction.execute("MATCH (company:Company)" + " WHERE company.name='Baeldung'" + " DELETE company"); - Result result = graphDb.execute("MATCH (company:Company)" + + Result result = transaction.execute("MATCH (company:Company)" + " WHERE company.name='Baeldung'" + " RETURN company"); @@ -146,14 +158,13 @@ public class Neo4jLiveTest { @Test public void testBindings() { - graphDb.beginTx(); - + transaction = graphDb.beginTx(); Map params = new HashMap<>(); params.put("name", "baeldung"); params.put("make", "tesla"); params.put("model", "modelS"); - Result result = graphDb.execute("CREATE (baeldung:Company {name:$name}) " + + Result result = transaction.execute("CREATE (baeldung:Company {name:$name}) " + "-[:owns]-> (tesla:Car {make: $make, model: $model})" + "RETURN baeldung, tesla", params); diff --git a/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java new file mode 100644 index 0000000000..aa9dd84ed6 --- /dev/null +++ b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java @@ -0,0 +1,58 @@ +package com.baeldung.neo4j; + +import static com.baeldung.neo4j.TestContainersTestBase.getDriver; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.neo4j.ogm.model.Result; +import org.neo4j.ogm.session.Session; +import org.neo4j.ogm.session.SessionFactory; + +import com.baeldung.neo4j.domain.Car; +import com.baeldung.neo4j.domain.Company; + +/** + * To run this test you will need to have an instance of the docker running on your machine (Docker desktop - for Windows and Docker instance for linux) + * After your docker instance is up run this test + */ +public class Neo4jOgmLiveTest { + + private static SessionFactory sessionFactory; + private static Session session; + + @BeforeAll + public static void oneTimeSetUp() { + sessionFactory = new SessionFactory(getDriver(), "com.baeldung.neo4j.domain"); + session = sessionFactory.openSession(); + session.purgeDatabase(); + } + + @Test + void testOgm() { + Car tesla = new Car("tesla", "modelS"); + Company baeldung = new Company("baeldung"); + + baeldung.setCar(tesla); + + session.save(baeldung); + + assertEquals(1, session.countEntitiesOfType(Company.class)); + + Map params = new HashMap<>(); + params.put("make", "tesla"); + Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" + + " WHERE car.make=$make" + + " RETURN company", params); + + Map firstResult = result.iterator().next(); + + assertEquals(1, firstResult.size()); + + Company actual = (Company) firstResult.get("company"); + assertEquals(actual.getName(), baeldung.getName()); + } +} diff --git a/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/TestContainersTestBase.java b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/TestContainersTestBase.java new file mode 100644 index 0000000000..eed2237454 --- /dev/null +++ b/persistence-modules/neo4j/src/test/java/com/baeldung/neo4j/TestContainersTestBase.java @@ -0,0 +1,132 @@ +package com.baeldung.neo4j; + +import static org.neo4j.ogm.drivers.bolt.driver.BoltDriver.CONFIG_PARAMETER_BOLT_LOGGING; + +import java.util.Locale; +import java.util.Optional; + +import org.neo4j.driver.AccessMode; +import org.neo4j.driver.AuthTokens; +import org.neo4j.driver.GraphDatabase; +import org.neo4j.driver.Logging; +import org.neo4j.driver.Session; +import org.neo4j.driver.SessionConfig; +import org.neo4j.ogm.config.Configuration; +import org.neo4j.ogm.driver.Driver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.Neo4jContainer; +import org.testcontainers.utility.TestcontainersConfiguration; + +/** + * Reference: https://github.com/neo4j/neo4j-ogm/blob/master/neo4j-ogm-tests/neo4j-ogm-integration-tests/src/test/java/org/neo4j/ogm/testutil/TestContainersTestBase.java + */ +public class TestContainersTestBase { + + public static final Logger LOGGER = LoggerFactory.getLogger(TestContainersTestBase.class); + + public static final Driver driver; + + public static final String version; + + public static final String DEFAULT_IMAGE = "neo4j:5"; + + public static final String SYS_PROPERTY_ACCEPT_AND_USE_COMMERCIAL_EDITION = "NEO4J_OGM_NEO4J_ACCEPT_AND_USE_COMMERCIAL_EDITION"; + + public static final String SYS_PROPERTY_IMAGE_NAME = "NEO4J_OGM_NEO4J_IMAGE_NAME"; + + public static final String SYS_PROPERTY_NEO4J_URL = "NEO4J_OGM_NEO4J_URL"; + + public static final String SYS_PROPERTY_NEO4J_PASSWORD = "NEO4J_OGM_NEO4J_PASSWORD"; + + public static final String DEFAULT_PASSWORD = "12345"; + + public static Neo4jContainer neo4jServer; + + public static Configuration.Builder baseConfigurationBuilder; + + public static final String NEO4J_URL = Optional.ofNullable(System.getenv(SYS_PROPERTY_NEO4J_URL)).orElse(""); + + public static final String NEO4J_PASSWORD = Optional.ofNullable(System.getenv(SYS_PROPERTY_NEO4J_PASSWORD)).orElse("").trim(); + + static { + + boolean acceptAndUseCommercialEdition = hasAcceptedAndWantsToUseCommercialEdition(); + + if (!(NEO4J_URL.isEmpty() || NEO4J_PASSWORD.isEmpty())) { + LOGGER.info("Using Neo4j instance at {}.", NEO4J_URL); + driver = new org.neo4j.ogm.drivers.bolt.driver.BoltDriver(); + baseConfigurationBuilder = new Configuration.Builder() + .uri(NEO4J_URL) + .verifyConnection(true) + .withCustomProperty(CONFIG_PARAMETER_BOLT_LOGGING, Logging.slf4j()) + .credentials("neo4j", NEO4J_PASSWORD); + driver.configure(baseConfigurationBuilder.build()); + version = extractVersionFromBolt(); + } else { + LOGGER.info("Using Neo4j test container."); + String imageName = Optional.ofNullable(System.getenv(SYS_PROPERTY_IMAGE_NAME)) + .orElse(DEFAULT_IMAGE + (acceptAndUseCommercialEdition ? "-enterprise" : "")); + + version = extractVersionFromDockerImage(imageName); + + boolean containerReuseSupported = TestcontainersConfiguration + .getInstance().environmentSupportsReuse(); + neo4jServer = new Neo4jContainer<>(imageName) + .withReuse(containerReuseSupported); + + if (acceptAndUseCommercialEdition) { + neo4jServer.withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes"); + } + neo4jServer.withAdminPassword(DEFAULT_PASSWORD).start(); + + driver = new org.neo4j.ogm.drivers.bolt.driver.BoltDriver(); + + baseConfigurationBuilder = new Configuration.Builder() + .uri(neo4jServer.getBoltUrl()) + .credentials("neo4j", DEFAULT_PASSWORD) + .verifyConnection(true) + .withCustomProperty(CONFIG_PARAMETER_BOLT_LOGGING, Logging.slf4j()); + + driver.configure(baseConfigurationBuilder.build()); + + Runtime.getRuntime().addShutdownHook(new Thread(neo4jServer::stop)); + } + } + + public static org.neo4j.driver.Driver getNewBoltConnection() { + + if (neo4jServer != null) { + return GraphDatabase.driver(neo4jServer.getBoltUrl(), AuthTokens.basic("neo4j", DEFAULT_PASSWORD)); + } else { + return GraphDatabase.driver(NEO4J_URL, AuthTokens.basic("neo4j", NEO4J_PASSWORD)); + } + } + + public static boolean hasAcceptedAndWantsToUseCommercialEdition() { + return Optional.ofNullable( + System.getenv(TestContainersTestBase.SYS_PROPERTY_ACCEPT_AND_USE_COMMERCIAL_EDITION)) + .orElse("no").toLowerCase(Locale.ENGLISH).equals("yes"); + } + + public static Driver getDriver() { + return driver; + } + + private static String extractVersionFromDockerImage(String imageName) { + return imageName.replace("neo4j:", "").replace("neo4j/neo4j-experimental:", "").replace("-enterprise", ""); + } + + private static String extractVersionFromBolt() { + + org.neo4j.driver.Driver driver = getDriver().unwrap(org.neo4j.driver.Driver.class); + + String version; + SessionConfig sessionConfig = SessionConfig.builder().withDefaultAccessMode(AccessMode.READ).build(); + try (Session session = driver.session(sessionConfig)) { + version = (String) session.run("CALL dbms.components() YIELD versions").single().get("versions").asList().get(0); + } + return version.toLowerCase(Locale.ENGLISH); + } + +} \ No newline at end of file diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 9361e26d7d..9eb7ca1f1d 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -40,8 +40,6 @@ java-jpa java-jpa-2 java-jpa-3 - - java-mongodb-2 java-mongodb-3 java-mongodb-queries @@ -68,7 +66,6 @@ spring-data-arangodb spring-data-cassandra spring-data-cassandra-test - spring-data-cosmosdb spring-data-couchbase-2 spring-data-dynamodb @@ -90,10 +87,9 @@ spring-data-jpa-repo-2 spring-data-jdbc spring-data-keyvalue - + spring-data-mongodb spring-data-mongodb-2 spring-data-mongodb-reactive - spring-data-redis @@ -102,17 +98,19 @@ spring-data-solr - + spring-jpa + spring-jpa-2 spring-jdbc spring-jooq spring-mybatis spring-persistence-simple + spring-data-yugabytedb fauna spring-data-rest java-mongodb questdb + neo4j diff --git a/persistence-modules/spring-boot-persistence-2/pom.xml b/persistence-modules/spring-boot-persistence-2/pom.xml index 260c558875..6bca6df2b9 100644 --- a/persistence-modules/spring-boot-persistence-2/pom.xml +++ b/persistence-modules/spring-boot-persistence-2/pom.xml @@ -111,19 +111,10 @@ hsqldb - com.oracle.database.jdbc - ojdbc8 - ${oracle-database.version} - - - com.oracle.database.ha - ons - ${oracle-database.version} - - - com.oracle.database.jdbc - ucp - ${oracle-database.version} + com.oracle.database.spring + oracle-spring-boot-starter-ucp + 3.1.0 + pom diff --git a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java index aa448bc44a..6ef780fcef 100644 --- a/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java +++ b/persistence-modules/spring-boot-persistence-2/src/test/java/com/baeldung/spring/oracle/pooling/SpringOraclePoolingApplicationOracleUCPLiveTest.java @@ -15,7 +15,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = {SpringOraclePoolingApplication.class}) @ActiveProfiles({"oracle-pooling-basic"}) -@TestPropertySource(properties = "spring.datasource.type=oracle.ucp.jdbc.UCPDataSource") +@TestPropertySource(properties = "spring.datasource.type=oracle.ucp.jdbc.PoolDataSource") public class SpringOraclePoolingApplicationOracleUCPLiveTest { @Autowired @@ -23,8 +23,7 @@ public class SpringOraclePoolingApplicationOracleUCPLiveTest { @Test public void givenOracleUCPConfiguration_thenBuildsOraclePoolDataSource() { - assertTrue(dataSource instanceof oracle.ucp.jdbc.UCPDataSource); + assertTrue(dataSource instanceof oracle.ucp.jdbc.PoolDataSource); } - } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/README.md b/persistence-modules/spring-boot-persistence-mongodb-3/README.md index f0cc97619a..ee6a96397a 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb-3/README.md @@ -1,3 +1,4 @@ # Relevant Articles - [How to Insert a HashMap Into MongoDB With Java?](https://www.baeldung.com/java-mongodb-insert-hashmap) +- [MongoDB – Field Level Encryption](https://www.baeldung.com/mongodb-field-level-encryption) - More articles: [[<--prev]](../spring-boot-persistence-mongodb-2) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/Citizen.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/Citizen.java index 11e776123a..2be2c13463 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/Citizen.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/Citizen.java @@ -9,15 +9,6 @@ public class Citizen { private String email; private Integer birthYear; - public Citizen() { - } - - public Citizen(EncryptedCitizen encryptedCitizen) { - if (encryptedCitizen != null) { - this.name = encryptedCitizen.getName(); - } - } - public String getName() { return name; } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/EncryptedCitizen.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/EncryptedCitizen.java index c7ca5566a9..64ded0fcc2 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/EncryptedCitizen.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/data/EncryptedCitizen.java @@ -10,13 +10,6 @@ public class EncryptedCitizen { private Binary email; private Binary birthYear; - public EncryptedCitizen() { - } - - public EncryptedCitizen(Citizen citizen) { - this.name = citizen.getName(); - } - public String getName() { return name; } diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java index c93b00f3f8..f7767c48de 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/service/CitizenService.java @@ -1,6 +1,8 @@ package com.baeldung.boot.csfle.service; import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import org.bson.BsonBinary; @@ -26,22 +28,33 @@ public class CitizenService { public static final String DETERMINISTIC_ALGORITHM = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"; public static final String RANDOM_ALGORITHM = "AEAD_AES_256_CBC_HMAC_SHA_512-Random"; - @Autowired - private MongoTemplate mongo; + private final MongoTemplate mongo; + private final EncryptionConfig encryptionConfig; + private final ClientEncryption clientEncryption; - @Autowired - private EncryptionConfig encryptionConfig; - - @Autowired - private ClientEncryption clientEncryption; + public CitizenService(MongoTemplate mongo, EncryptionConfig encryptionConfig, ClientEncryption clientEncryption) { + this.mongo = mongo; + this.encryptionConfig = encryptionConfig; + this.clientEncryption = clientEncryption; + } public Object save(Citizen citizen) { if (encryptionConfig.isAutoEncryption()) { return mongo.save(citizen); } else { - EncryptedCitizen encryptedCitizen = new EncryptedCitizen(citizen); - encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); - encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); + EncryptedCitizen encryptedCitizen = new EncryptedCitizen(); + encryptedCitizen.setName(citizen.getName()); + if (citizen.getEmail() != null) { + encryptedCitizen.setEmail(encrypt(citizen.getEmail(), DETERMINISTIC_ALGORITHM)); + } else { + encryptedCitizen.setEmail(null); + + } + if (citizen.getBirthYear() != null) { + encryptedCitizen.setBirthYear(encrypt(citizen.getBirthYear(), RANDOM_ALGORITHM)); + } else { + encryptedCitizen.setBirthYear(null); + } return mongo.save(encryptedCitizen); } @@ -77,18 +90,9 @@ public class CitizenService { } } - public Binary encrypt(Object value, String algorithm) { - if (value == null) - return null; - - BsonValue bsonValue; - if (value instanceof Integer) { - bsonValue = new BsonInt32((Integer) value); - } else if (value instanceof String) { - bsonValue = new BsonString((String) value); - } else { - throw new IllegalArgumentException("unsupported type: " + value.getClass()); - } + public Binary encrypt(BsonValue bsonValue, String algorithm) { + Objects.requireNonNull(bsonValue); + Objects.requireNonNull(algorithm); EncryptOptions options = new EncryptOptions(algorithm); options.keyId(encryptionConfig.getDataKeyId()); @@ -97,29 +101,40 @@ public class CitizenService { return new Binary(encryptedValue.getType(), encryptedValue.getData()); } + public Binary encrypt(String value, String algorithm) { + Objects.requireNonNull(value); + Objects.requireNonNull(algorithm); + + return encrypt(new BsonString(value), algorithm); + } + + public Binary encrypt(Integer value, String algorithm) { + Objects.requireNonNull(value); + Objects.requireNonNull(algorithm); + + return encrypt(new BsonInt32(value), algorithm); + } + public BsonValue decryptProperty(Binary value) { - if (value == null) - return null; + Objects.requireNonNull(value); return clientEncryption.decrypt(new BsonBinary(value.getType(), value.getData())); } private Citizen decrypt(EncryptedCitizen encrypted) { - if (encrypted == null) - return null; + Objects.requireNonNull(encrypted); - Citizen citizen = new Citizen(encrypted); + Citizen citizen = new Citizen(); + citizen.setName(encrypted.getName()); - BsonValue decryptedBirthYear = decryptProperty(encrypted.getBirthYear()); + BsonValue decryptedBirthYear = encrypted.getBirthYear() != null ? decryptProperty(encrypted.getBirthYear()) : null; if (decryptedBirthYear != null) { - citizen.setBirthYear(decryptedBirthYear.asInt32() - .intValue()); + citizen.setBirthYear(decryptedBirthYear.asInt32().intValue()); } - BsonValue decryptedEmail = decryptProperty(encrypted.getEmail()); + BsonValue decryptedEmail = encrypted.getEmail() != null ? decryptProperty(encrypted.getEmail()) : null; if (decryptedEmail != null) { - citizen.setEmail(decryptedEmail.asString() - .getValue()); + citizen.setEmail(decryptedEmail.asString().getValue()); } return citizen; diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java index 7a2b2605cd..b198b97d57 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java +++ b/persistence-modules/spring-boot-persistence-mongodb-3/src/main/java/com/baeldung/boot/csfle/web/CitizenController.java @@ -17,8 +17,11 @@ import com.baeldung.boot.csfle.service.CitizenService; @RequestMapping("/citizen") public class CitizenController { - @Autowired - private CitizenService service; + private final CitizenService service; + + public CitizenController(CitizenService service) { + this.service = service; + } @GetMapping public List get() { diff --git a/persistence-modules/spring-boot-persistence/README.md b/persistence-modules/spring-boot-persistence/README.md index 88526cdb89..6bbc2b37ae 100644 --- a/persistence-modules/spring-boot-persistence/README.md +++ b/persistence-modules/spring-boot-persistence/README.md @@ -7,4 +7,5 @@ - [Resolving “Failed to Configure a DataSource” Error](https://www.baeldung.com/spring-boot-failed-to-configure-data-source) - [Hibernate Field Naming with Spring Boot](https://www.baeldung.com/hibernate-field-naming-spring-boot) - [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate) +- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source) - More articles: [[more -->]](../spring-boot-persistence-2) diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 06425cceb7..e6f5ea9cae 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -175,7 +175,7 @@ 4.3.4.RELEASE 4.5.2 5.1.0 - 1.11.64 + 1.12.331 3.3.7-1 1.0.392 1.21.1 diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java index 6cbd5b0a5a..61de1163b8 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java @@ -1,6 +1,8 @@ package com.baeldung.spring.data.dynamodb.repository; +import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; @@ -10,17 +12,24 @@ import com.baeldung.spring.data.dynamodb.model.ProductInfo; import com.baeldung.spring.data.dynamodb.repositories.ProductInfoRepository; import com.baeldung.spring.data.dynamodb.repository.rule.LocalDbCreationRule; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; +import java.util.Optional; +import java.util.Properties; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.core.Is.is; @@ -31,23 +40,40 @@ import static org.junit.Assert.assertThat; @SpringBootTest(classes = Application.class) @WebAppConfiguration @ActiveProfiles("local") -@TestPropertySource(properties = { "amazon.dynamodb.endpoint=http://localhost:8000/", "amazon.aws.accesskey=test1", "amazon.aws.secretkey=test231" }) public class ProductInfoRepositoryIntegrationTest { @ClassRule public static LocalDbCreationRule dynamoDB = new LocalDbCreationRule(); - - private DynamoDBMapper dynamoDBMapper; + private static DynamoDBMapper dynamoDBMapper; + private static AmazonDynamoDB amazonDynamoDB; @Autowired - private AmazonDynamoDB amazonDynamoDB; + private ProductInfoRepository repository; - @Autowired - ProductInfoRepository repository; + private static final String DYNAMODB_ENDPOINT = "amazon.dynamodb.endpoint"; + private static final String AWS_ACCESSKEY = "amazon.aws.accesskey"; + private static final String AWS_SECRETKEY = "amazon.aws.secretkey"; private static final String EXPECTED_COST = "20"; private static final String EXPECTED_PRICE = "50"; + @BeforeClass + public static void setupClass() { + Properties testProperties = loadFromFileInClasspath("application.properties") + .filter(properties -> !isEmpty(properties.getProperty(AWS_ACCESSKEY))) + .filter(properties -> !isEmpty(properties.getProperty(AWS_SECRETKEY))) + .filter(properties -> !isEmpty(properties.getProperty(DYNAMODB_ENDPOINT))) + .orElseThrow(() -> new RuntimeException("Unable to get all of the required test property values")); + + String amazonAWSAccessKey = testProperties.getProperty(AWS_ACCESSKEY); + String amazonAWSSecretKey = testProperties.getProperty(AWS_SECRETKEY); + String amazonDynamoDBEndpoint = testProperties.getProperty(DYNAMODB_ENDPOINT); + + amazonDynamoDB = new AmazonDynamoDBClient(new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey)); + amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint); + dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB); + } + @Before public void setup() throws Exception { @@ -77,4 +103,28 @@ public class ProductInfoRepositoryIntegrationTest { assertThat(result.size(), is(greaterThan(0))); assertThat(result.get(0).getCost(), is(equalTo(EXPECTED_COST))); } + + private static boolean isEmpty(String inputString) { + return inputString == null || "".equals(inputString); + } + + private static Optional loadFromFileInClasspath(String fileName) { + InputStream stream = null; + try { + Properties config = new Properties(); + Path configLocation = Paths.get(ClassLoader.getSystemResource(fileName).toURI()); + stream = Files.newInputStream(configLocation); + config.load(stream); + return Optional.of(config); + } catch (Exception e) { + return Optional.empty(); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + } + } + } + } } diff --git a/persistence-modules/spring-data-elasticsearch/README.md b/persistence-modules/spring-data-elasticsearch/README.md index 22126c2f00..dfa581a59a 100644 --- a/persistence-modules/spring-data-elasticsearch/README.md +++ b/persistence-modules/spring-data-elasticsearch/README.md @@ -6,6 +6,7 @@ - [Guide to Elasticsearch in Java](https://www.baeldung.com/elasticsearch-java) - [Geospatial Support in ElasticSearch](https://www.baeldung.com/elasticsearch-geo-spatial) - [A Simple Tagging Implementation with Elasticsearch](https://www.baeldung.com/elasticsearch-tagging) +- [What Is Elasticsearch?](https://www.baeldung.com/java-elasticsearch) ### Build the Project with Tests Running ``` diff --git a/persistence-modules/spring-data-jpa-repo-3/README.md b/persistence-modules/spring-data-jpa-repo-3/README.md index 93cc9379f7..623ac66bb3 100644 --- a/persistence-modules/spring-data-jpa-repo-3/README.md +++ b/persistence-modules/spring-data-jpa-repo-3/README.md @@ -7,4 +7,5 @@ This module contains articles about Spring Data JPA. - [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list) - [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids) - [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush) +- [Difference Between findBy and findOneBy in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-findby-vs-findoneby) - More articles: [[<-- prev]](../spring-data-jpa-repo-2) diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Person.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Person.java new file mode 100644 index 0000000000..0f58e403ab --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/entity/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.data.jpa.listrepositories.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private int id; + private String firstName; + private String lastName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + 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; + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepository.java new file mode 100644 index 0000000000..0397cf5063 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepository.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.data.jpa.listrepositories.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.spring.data.jpa.listrepositories.entity.Person; + +@Repository +public interface PersonRepository extends JpaRepository { + Person findByFirstName(String firstName); + + List findByLastName(String lastName); + + Person findOneByFirstName(String firstName); + + List findOneByLastName(String lastName); +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties index 5a1841e2ad..cd6dbe3994 100644 --- a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/application.properties @@ -1,2 +1,5 @@ +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=none + logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/data.sql b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/data.sql new file mode 100644 index 0000000000..50bd326155 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/data.sql @@ -0,0 +1,4 @@ +INSERT INTO person (id, first_name, last_name) VALUES(1, 'Azhrioun', 'Abderrahim'); +INSERT INTO person (id, first_name, last_name) VALUES(2, 'Brian', 'Wheeler'); +INSERT INTO person (id, first_name, last_name) VALUES(3, 'Stella', 'Anderson'); +INSERT INTO person (id, first_name, last_name) VALUES(4, 'Stella', 'Wheeler'); \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/resources/schema.sql b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/schema.sql new file mode 100644 index 0000000000..c8be0eb781 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/resources/schema.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS person; +CREATE TABLE person( + id INT PRIMARY KEY, + first_name VARCHAR(200), + last_name VARCHAR(200) +) \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepositoryIntegrationTest.java new file mode 100644 index 0000000000..f93b822ffb --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/listrepositories/repository/PersonRepositoryIntegrationTest.java @@ -0,0 +1,66 @@ +package com.baeldung.spring.data.jpa.listrepositories.repository; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +import com.baeldung.spring.data.jpa.listrepositories.entity.Person; + +@DataJpaTest +class PersonRepositoryIntegrationTest { + + @Autowired + private PersonRepository personRepository; + + @Test + void givenFirstName_whenCallingFindByFirstName_ThenReturnOnePerson() { + Person person = personRepository.findByFirstName("Azhrioun"); + + assertNotNull(person); + assertEquals("Abderrahim", person.getLastName()); + } + + @Test + void givenLastName_whenCallingFindByLastName_ThenReturnList() { + List person = personRepository.findByLastName("Wheeler"); + + assertEquals(2, person.size()); + } + + @Test + void givenFirstName_whenCallingFindOneByFirstName_ThenReturnOnePerson() { + Person person = personRepository.findOneByFirstName("Azhrioun"); + + assertNotNull(person); + assertEquals("Abderrahim", person.getLastName()); + } + + @Test + void givenLastName_whenCallingFindOneByLastName_ThenReturnList() { + List persons = personRepository.findOneByLastName("Wheeler"); + + assertEquals(2, persons.size()); + } + + @Test + void givenFirstName_whenCallingFindByFirstName_ThenThrowException() { + IncorrectResultSizeDataAccessException exception = assertThrows(IncorrectResultSizeDataAccessException.class, () -> personRepository.findByFirstName("Stella")); + + assertEquals("query did not return a unique result: 2", exception.getMessage()); + } + + @Test + void givenFirstName_whenCallingFindOneByFirstName_ThenThrowException() { + IncorrectResultSizeDataAccessException exception = assertThrows(IncorrectResultSizeDataAccessException.class, () -> personRepository.findOneByFirstName("Stella")); + + assertEquals("query did not return a unique result: 2", exception.getMessage()); + } + +} diff --git a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java index 8f86e8ce49..7d4a208d26 100644 --- a/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java +++ b/persistence-modules/spring-data-jpa-repo/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java @@ -51,12 +51,9 @@ public interface UserRepository extends JpaRepository { List findByAgeIn(Collection ages); - @Query(value = "select * from users where (name = :nameParam OR birth_date <> :birthDateParam)", nativeQuery = true) - List findByNameOrBirthDate(@Param(value = "nameParam") String nameParam, @Param(value = "birthDateParam") ZonedDateTime birthDateParam); + List findByNameOrAge(String name, Integer age); - @Query(value = "select * from users where (name = :nameParam OR birth_date <> :birthDateParam) and active = :activeParam", nativeQuery = true) - List findByNameOrBirthDateAndActive(@Param(value = "nameParam") String nameParam, @Param(value = "birthDateParam") ZonedDateTime birthDateParam, - @Param(value = "activeParam") Boolean activeParam); + List findByNameOrAgeAndActive(String name, Integer age, Boolean active); List findByNameOrderByName(String name); diff --git a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java index 75e0db253f..cf479780a1 100644 --- a/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-repo/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java @@ -153,15 +153,15 @@ public class UserRepositoryIntegrationTest { } @Test - public void whenByNameOrBirthDate() { + public void whenByNameOrAge() { - assertEquals(4, userRepository.findByNameOrBirthDate(USER_NAME_ADAM, BIRTHDATE).size()); + assertEquals(3, userRepository.findByNameOrAge(USER_NAME_ADAM, 20).size()); } @Test - public void whenByNameOrBirthDateAndActive() { + public void whenByNameOrAgeAndActive() { - assertEquals(2, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size()); + assertEquals(2, userRepository.findByNameOrAgeAndActive(USER_NAME_ADAM, 20, false).size()); } @Test diff --git a/persistence-modules/spring-data-mongodb/pom.xml b/persistence-modules/spring-data-mongodb/pom.xml index afb5e8b9c1..87cf1acaf8 100644 --- a/persistence-modules/spring-data-mongodb/pom.xml +++ b/persistence-modules/spring-data-mongodb/pom.xml @@ -103,13 +103,13 @@ - 3.0.3.RELEASE - 4.3.1 + 3.4.7 + 5.0.0 1.1.3 4.1.0 - 3.2.0.RELEASE - 4.0.5 - 3.2.6 + 3.5.4 + 4.6.1 + 4.6.3 \ No newline at end of file diff --git a/persistence-modules/spring-data-neo4j/README.md b/persistence-modules/spring-data-neo4j/README.md index dc54de0e31..0f9a6d99e8 100644 --- a/persistence-modules/spring-data-neo4j/README.md +++ b/persistence-modules/spring-data-neo4j/README.md @@ -2,7 +2,6 @@ ### Relevant Articles: - [Introduction to Spring Data Neo4j](https://www.baeldung.com/spring-data-neo4j-intro) -- [A Guide to Neo4J with Java](https://www.baeldung.com/java-neo4j) ### Build the Project with Tests Running ``` diff --git a/persistence-modules/spring-data-neo4j/pom.xml b/persistence-modules/spring-data-neo4j/pom.xml index 8c5030779b..33f2966db3 100644 --- a/persistence-modules/spring-data-neo4j/pom.xml +++ b/persistence-modules/spring-data-neo4j/pom.xml @@ -14,26 +14,11 @@ - - org.neo4j - neo4j - ${neo4j.version} - - - org.neo4j - neo4j-ogm-core - ${neo4j-ogm.version} - org.neo4j neo4j-ogm-embedded-driver ${neo4j-ogm.version} - - org.neo4j.driver - neo4j-java-driver - ${neo4j-java-driver.version} - org.springframework.data spring-data-neo4j @@ -51,24 +36,6 @@ ${spring-boot.version} test - - org.neo4j - neo4j-kernel - ${neo4j.version} - test-jar - - - org.neo4j.app - neo4j-server - ${neo4j.version} - test-jar - - - commons-logging - commons-logging - - - org.neo4j neo4j-ogm-test @@ -89,7 +56,6 @@ - 1.6.2 3.4.6 5.0.1.RELEASE 1.1 diff --git a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java deleted file mode 100644 index bf187ccb2d..0000000000 --- a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.baeldung.neo4j; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; - -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; -import org.neo4j.driver.v1.AuthTokens; -import org.neo4j.driver.v1.Driver; -import org.neo4j.driver.v1.GraphDatabase; -import org.neo4j.driver.v1.Session; -import org.neo4j.driver.v1.StatementResult; - -@Ignore -public class Neo4JServerLiveTest { - - @Test - public void standAloneDriver() { - Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "12345")); - Session session = driver.session(); - - session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " + - "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + - "RETURN baeldung, tesla"); - - StatementResult result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" + - "WHERE car.make='tesla' and car.model='modelX'" + - "RETURN company.name"); - - Assert.assertTrue(result.hasNext()); - Assert.assertEquals(result.next().get("company.name").asString(), "Baeldung"); - - session.close(); - driver.close(); - } - - @Test - public void standAloneJdbc() throws Exception { - Connection con = DriverManager.getConnection("jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic"); - - // Querying - try (Statement stmt = con.createStatement()) { - stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " + - "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" + - "RETURN baeldung, tesla"); - - ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" + - "WHERE car.make='tesla' and car.model='modelX'" + - "RETURN company.name"); - - while (rs.next()) { - Assert.assertEquals(rs.getString("company.name"), "Baeldung"); - } - } - con.close(); - } -} diff --git a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java deleted file mode 100644 index 96e5e76402..0000000000 --- a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.baeldung.neo4j; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; -import org.neo4j.ogm.config.Configuration; -import org.neo4j.ogm.model.Result; -import org.neo4j.ogm.session.Session; -import org.neo4j.ogm.session.SessionFactory; - -import com.baeldung.spring.data.neo4j.domain.Car; -import com.baeldung.spring.data.neo4j.domain.Company; - -public class Neo4jOgmLiveTest { - - @Test - public void testOgm() { - Configuration conf = new Configuration.Builder().build(); - - SessionFactory factory = new SessionFactory(conf, "com.baeldung.spring.data.neo4j.domain"); - Session session = factory.openSession(); - - Car tesla = new Car("tesla", "modelS"); - Company baeldung = new Company("baeldung"); - - baeldung.setCar(tesla); - - session.save(baeldung); - - Assert.assertEquals(1, session.countEntitiesOfType(Company.class)); - - Map params = new HashMap<>(); - params.put("make", "tesla"); - Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" + - " WHERE car.make=$make" + - " RETURN company", params); - - Map firstResult = result.iterator().next(); - - Assert.assertEquals(firstResult.size(), 1); - - Company actual = (Company) firstResult.get("company"); - Assert.assertEquals(actual.getName(), baeldung.getName()); - } -} diff --git a/persistence-modules/spring-data-yugabytedb/pom.xml b/persistence-modules/spring-data-yugabytedb/pom.xml new file mode 100644 index 0000000000..cf85988ac3 --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + spring-data-yugabytedb + 1.0 + spring-data-yugabytedb + jar + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.postgresql + postgresql + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + diff --git a/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/Main.java b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/Main.java new file mode 100644 index 0000000000..8638528f6a --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/Main.java @@ -0,0 +1,32 @@ +package com.baeldung; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main implements CommandLineRunner { + + @Autowired + private UserRepository userRepository; + + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } + + @Override + public void run(String... args) throws InterruptedException { + + int iterationCount = 1_000; + int elementsPerIteration = 100; + + for (int i = 0; i < iterationCount; i++) { + for (long j = 0; j < elementsPerIteration; j++) { + User user = new User(); + userRepository.save(user); + } + Thread.sleep(1000); + } + } +} diff --git a/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/User.java b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/User.java new file mode 100644 index 0000000000..54bbf2617c --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/User.java @@ -0,0 +1,41 @@ +package com.baeldung; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; + } +} diff --git a/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/UserRepository.java b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/UserRepository.java new file mode 100644 index 0000000000..d04047d416 --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/main/java/com/baeldung/UserRepository.java @@ -0,0 +1,6 @@ +package com.baeldung; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-data-yugabytedb/src/main/resources/application.properties b/persistence-modules/spring-data-yugabytedb/src/main/resources/application.properties new file mode 100644 index 0000000000..fdb3d50ec8 --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.datasource.url=jdbc:postgresql://localhost:5433/yugabyte +spring.datasource.username=yugabyte +spring.datasource.password=yugabyte +spring.jpa.hibernate.ddl-auto=create diff --git a/persistence-modules/spring-data-yugabytedb/src/main/resources/docker-compose.yml b/persistence-modules/spring-data-yugabytedb/src/main/resources/docker-compose.yml new file mode 100644 index 0000000000..6d95320525 --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/main/resources/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + yugabytedb: + image: yugabytedb/yugabyte:latest + container_name: yugabyte + user: root + ports: + - '5433:5433' + - '7000:7000' + - '9000:9000' + command: ["bin/yugabyted", "start", "--daemon=false"] + diff --git a/persistence-modules/spring-data-yugabytedb/src/test/java/com/baeldung/YugabyteDBLiveTest.java b/persistence-modules/spring-data-yugabytedb/src/test/java/com/baeldung/YugabyteDBLiveTest.java new file mode 100644 index 0000000000..8a9de9bab4 --- /dev/null +++ b/persistence-modules/spring-data-yugabytedb/src/test/java/com/baeldung/YugabyteDBLiveTest.java @@ -0,0 +1,37 @@ +package com.baeldung; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +/* + To run this test we need to run the databases first. + A dedicated docker-compose.yml file is located under the resources directory. + We can run it by simple executing `docker-compose up`. + */ +@SpringJUnitConfig +@SpringBootTest +@TestPropertySource("classpath:application.properties") +public class YugabyteDBLiveTest { + + @Autowired + private UserRepository userRepository; + + @Test + void givenTwoUsers_whenPersistUsingJPARepository_thenUserAreSaved() { + User user1 = new User(); + user1.setName("Alex"); + User user2 = new User(); + user2.setName("John"); + userRepository.save(user1); + userRepository.save(user2); + List allUsers = userRepository.findAll(); + assertEquals(2, allUsers.size()); + } +} diff --git a/persistence-modules/spring-jpa-2/pom.xml b/persistence-modules/spring-jpa-2/pom.xml index 974dd41df9..9abf888fb2 100644 --- a/persistence-modules/spring-jpa-2/pom.xml +++ b/persistence-modules/spring-jpa-2/pom.xml @@ -71,7 +71,7 @@ org.postgresql postgresql - 42.4.0 + ${postgresql.version} runtime @@ -97,15 +97,26 @@ ${org.springframework.version} test + + com.fasterxml.jackson.core + jackson-databind + ${jakson-databind.version} + + + com.fasterxml.jackson.core + jackson-core + ${jakson-core.version} + - 5.2.0.RELEASE - 2.2.6.RELEASE + 6.0.9 + 3.1.0 - 9.0.0.M26 - 2.1.214 + 10.1.9 + 2.15.1 + 2.14.2 \ No newline at end of file diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java index b3e979478f..f933ddd7ee 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/HibernateXMLConf.java @@ -1,21 +1,9 @@ package com.baeldung.hibernate.bootstrap; -import com.google.common.base.Preconditions; -import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.orm.hibernate5.HibernateTransactionManager; -import org.springframework.orm.hibernate5.LocalSessionFactoryBean; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; -import javax.sql.DataSource; -import java.util.Properties; - @Configuration @EnableTransactionManagement @ImportResource({ "classpath:hibernate5Configuration.xml" }) diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java index cae41db831..d260fed7a1 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/hibernate/bootstrap/model/TestEntity.java @@ -1,7 +1,7 @@ package com.baeldung.hibernate.bootstrap.model; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class TestEntity { diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Course.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Course.java index d824505629..9b035603c2 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Course.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Course.java @@ -1,6 +1,6 @@ package com.baeldung.manytomany.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRating.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRating.java index b89cc1dae9..6f6ec98482 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRating.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRating.java @@ -1,6 +1,6 @@ package com.baeldung.manytomany.model; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "course_rating") diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRatingKey.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRatingKey.java index a4b2df9b07..e9aa5d5bfa 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRatingKey.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRatingKey.java @@ -1,7 +1,7 @@ package com.baeldung.manytomany.model; -import javax.persistence.Column; -import javax.persistence.Embeddable; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; import java.io.Serializable; @Embeddable diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRegistration.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRegistration.java index ba914b564d..fc070287eb 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRegistration.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/CourseRegistration.java @@ -1,6 +1,6 @@ package com.baeldung.manytomany.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.time.LocalDateTime; @Entity diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Student.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Student.java index 53c5d88a57..1f9c0d1d72 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Student.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomany/model/Student.java @@ -1,6 +1,6 @@ package com.baeldung.manytomany.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java index d9906a21cd..ed102ffd77 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Author.java @@ -1,6 +1,6 @@ package com.baeldung.manytomanyremoval; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java index 4b49acd000..6fd56b1b88 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Book.java @@ -1,7 +1,6 @@ package com.baeldung.manytomanyremoval; - -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java index f7202f544c..c1bc5e4b16 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Category.java @@ -1,6 +1,6 @@ package com.baeldung.manytomanyremoval; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(name = "category") diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java index d229a9d0d7..21d059e50f 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/manytomanyremoval/Post.java @@ -1,7 +1,6 @@ package com.baeldung.manytomanyremoval; - -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/config/TenantFilter.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/config/TenantFilter.java index 3fbb5026f7..77ebced103 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/config/TenantFilter.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/config/TenantFilter.java @@ -4,8 +4,8 @@ import com.baeldung.multitenant.security.AuthenticationService; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; @Component diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/domain/Employee.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/domain/Employee.java index 883b70ca01..bedb1383a2 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/domain/Employee.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/domain/Employee.java @@ -1,11 +1,11 @@ package com.baeldung.multitenant.domain; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; @Entity @Table(name = "employee") diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationFilter.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationFilter.java index fa6bcfb5a0..f953bbc625 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationFilter.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationFilter.java @@ -4,11 +4,11 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.GenericFilterBean; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; public class AuthenticationFilter extends GenericFilterBean { diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java index 302058882d..00db7eebc4 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/AuthenticationService.java @@ -5,8 +5,8 @@ import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.Date; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/LoginFilter.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/LoginFilter.java index 9f6cbe6e16..fffa49d5b3 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/LoginFilter.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/LoginFilter.java @@ -9,10 +9,10 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; import java.util.Collections; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/SecurityConfiguration.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/SecurityConfiguration.java index 98c6a9c58d..acad0d61e4 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/SecurityConfiguration.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/multitenant/security/SecurityConfiguration.java @@ -2,32 +2,39 @@ package com.baeldung.multitenant.security; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { +public class SecurityConfiguration { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication() - .passwordEncoder(passwordEncoder()) - .withUser("user") - .password(passwordEncoder().encode("baeldung")) - .roles("tenant_1"); + @Bean + public InMemoryUserDetailsManager userDetailsService() { + UserDetails user1 = User + .withUsername("user") + .password(passwordEncoder().encode("baeldung")) + .roles("tenant_1") + .build(); - auth.inMemoryAuthentication() - .passwordEncoder(passwordEncoder()) - .withUser("admin") - .password(passwordEncoder().encode("baeldung")) - .roles("tenant_2"); + UserDetails user2 = User + .withUsername("admin") + .password(passwordEncoder().encode("baeldung")) + .roles("tenant_2") + .build(); + return new InMemoryUserDetailsManager(user1, user2); } @Bean @@ -35,22 +42,19 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { return new BCryptPasswordEncoder(); } - @Override - protected void configure(HttpSecurity http) throws Exception { + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + final AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); http - .authorizeRequests() - .antMatchers("/login").permitAll() - .anyRequest().authenticated() - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .addFilterBefore(new LoginFilter("/login", authenticationManager()), - UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) - .csrf().disable() - .headers().frameOptions().disable() - .and() - .httpBasic(); + .authorizeHttpRequests(authorize -> + authorize.requestMatchers("/login").permitAll().anyRequest().authenticated()) + .sessionManagement(securityContext -> securityContext.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .addFilterBefore(new LoginFilter("/login", authenticationManager), UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) + .csrf(AbstractHttpConfigurer::disable) + .headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) + .httpBasic(Customizer.withDefaults()); + + return http.build(); } } diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/AbstractJpaDAO.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/AbstractJpaDAO.java index e68a9281a0..01a83b8990 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/AbstractJpaDAO.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/AbstractJpaDAO.java @@ -1,7 +1,7 @@ package com.baeldung.spring.dao.generics; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/Foo.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/Foo.java index 33284d9b8e..113b8d3125 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/Foo.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/dao/generics/Foo.java @@ -2,7 +2,7 @@ package com.baeldung.spring.dao.generics; import org.hibernate.annotations.CacheConcurrencyStrategy; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/hibernate/Foo.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/hibernate/Foo.java index f92b510071..ae4f8e6722 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/hibernate/Foo.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/hibernate/Foo.java @@ -1,6 +1,6 @@ package com.baeldung.spring.hibernate; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java index 5add1e4a99..90a53240fb 100644 --- a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java +++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java @@ -2,10 +2,10 @@ package com.baeldung.spring.transaction; import java.io.Serializable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity @Table(name = "course") diff --git a/persistence-modules/spring-jpa-2/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-jpa-2/src/main/resources/persistence-mysql.properties index 9ba4f7602a..65a6e0dd10 100644 --- a/persistence-modules/spring-jpa-2/src/main/resources/persistence-mysql.properties +++ b/persistence-modules/spring-jpa-2/src/main/resources/persistence-mysql.properties @@ -5,7 +5,7 @@ jdbc.user=tutorialuser jdbc.pass=tutorialmy5ql # hibernate.X -hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java index c41423643a..4c18285baf 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateBootstrapIntegrationTest.java @@ -4,14 +4,12 @@ import com.baeldung.hibernate.bootstrap.model.TestEntity; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Commit; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.AnnotationConfigContextLoader; import org.springframework.test.context.transaction.TestTransaction; import org.springframework.transaction.annotation.Transactional; @@ -33,7 +31,7 @@ public class HibernateBootstrapIntegrationTest { TestEntity newEntity = new TestEntity(); newEntity.setId(1); - session.save(newEntity); + session.persist(newEntity); TestEntity searchEntity = session.find(TestEntity.class, 1); @@ -49,7 +47,7 @@ public class HibernateBootstrapIntegrationTest { TestEntity newEntity = new TestEntity(); newEntity.setId(1); - session.save(newEntity); + session.persist(newEntity); TestEntity searchEntity = session.find(TestEntity.class, 1); @@ -74,7 +72,7 @@ public class HibernateBootstrapIntegrationTest { Assert.assertNotNull(searchEntity); - session.delete(searchEntity); + session.remove(searchEntity); session.flush(); TestTransaction.end(); @@ -90,7 +88,7 @@ public class HibernateBootstrapIntegrationTest { Assert.assertNotNull(searchEntity); - session.delete(searchEntity); + session.remove(searchEntity); session.flush(); assertTrue(TestTransaction.isActive()); @@ -121,7 +119,7 @@ public class HibernateBootstrapIntegrationTest { TestEntity newEntity = new TestEntity(); newEntity.setId(1); - session.save(newEntity); + session.persist(newEntity); TestEntity searchEntity = session.find(TestEntity.class, 1); @@ -145,7 +143,7 @@ public class HibernateBootstrapIntegrationTest { Assert.assertNotNull(searchEntity); - session.delete(searchEntity); + session.remove(searchEntity); session.flush(); TestTransaction.flagForRollback(); @@ -162,7 +160,7 @@ public class HibernateBootstrapIntegrationTest { Assert.assertNotNull(searchEntity); - session.delete(searchEntity); + session.remove(searchEntity); session.flush(); assertTrue(TestTransaction.isActive()); diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java index 5b811ad576..d4ec1fe7ab 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/hibernate/bootstrap/HibernateXMLBootstrapIntegrationTest.java @@ -26,7 +26,7 @@ public class HibernateXMLBootstrapIntegrationTest { TestEntity newEntity = new TestEntity(); newEntity.setId(1); - session.save(newEntity); + session.persist(newEntity); TestEntity searchEntity = session.find(TestEntity.class, 1); diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyIntegrationTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyIntegrationTest.java index f5b02ec2c1..ee18853110 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyIntegrationTest.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyIntegrationTest.java @@ -11,8 +11,8 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyTestConfiguration.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyTestConfiguration.java index fa12828074..fb19d477fd 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyTestConfiguration.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomany/ManyToManyTestConfiguration.java @@ -11,7 +11,7 @@ import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java index f214fcdc2a..4e26429b14 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/BidirectionalRemovalUnitTest.java @@ -10,7 +10,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = TestContextConfig.class) diff --git a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java index b23b589fb7..16ba7b0687 100644 --- a/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java +++ b/persistence-modules/spring-jpa-2/src/test/java/com/baeldung/manytomanyremoval/UnidirectionalRemovalUnitTest.java @@ -10,7 +10,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; +import jakarta.persistence.EntityManager; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = TestContextConfig.class) diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md index aa9e833260..43dffa6973 100644 --- a/persistence-modules/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -6,7 +6,6 @@ - [Sorting with JPA](https://www.baeldung.com/jpa-sort) - [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database) - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) -- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source) - More articles: [[next -->]](/spring-jpa-2) ### Eclipse Config diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index 77074e835a..c08e4f823a 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -76,21 +76,21 @@ ${hibernate-validator.version} - javax.el - javax.el-api - ${javax.el-api.version} + org.glassfish.expressly + expressly + ${expressly-language.version} - javax.servlet - jstl - ${jstl.version} + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + ${jakarta-servlet-jpa-jstl-api.version} - javax.servlet - servlet-api + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet-api.version} provided - ${javax.servlet.servlet-api.version} @@ -115,17 +115,18 @@ - 5.1.5.RELEASE - 3.21.0-GA - 6.0.6 - 2.1.5.RELEASE + 6.0.6 + 3.29.2-GA + 8.0.33 + 3.1.0 - 2.5 + 6.0.0 - 6.0.15.Final - 1.4.01 - 2.2.5 + 8.0.0.Final + 2.0.2 2.1.214 + 5.0.0 + 3.0.0 \ No newline at end of file diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/Person.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/Person.java index b881535e05..8a6ae38886 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/Person.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/Person.java @@ -2,11 +2,11 @@ package com.baeldung.annotations; import java.util.Date; -import javax.persistence.Entity; -import javax.persistence.NamedStoredProcedureQueries; -import javax.persistence.NamedStoredProcedureQuery; -import javax.persistence.ParameterMode; -import javax.persistence.StoredProcedureParameter; +import jakarta.persistence.Entity; +import jakarta.persistence.NamedStoredProcedureQueries; +import jakarta.persistence.NamedStoredProcedureQuery; +import jakarta.persistence.ParameterMode; +import jakarta.persistence.StoredProcedureParameter; import com.baeldung.persistence.multiple.model.user.User; import org.springframework.data.annotation.CreatedBy; @@ -16,13 +16,13 @@ import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.Transient; @Entity -@NamedStoredProcedureQueries({ +@NamedStoredProcedureQueries({ @NamedStoredProcedureQuery( name = "count_by_name", procedureName = "person.count_by_name", parameters = { @StoredProcedureParameter( - mode = ParameterMode.IN, + mode = ParameterMode.IN, name = "name", type = String.class), @StoredProcedureParameter( diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/PersonRepository.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/PersonRepository.java index 77b7067f11..b6a1a41e48 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/PersonRepository.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/annotations/PersonRepository.java @@ -1,6 +1,6 @@ package com.baeldung.annotations; -import javax.persistence.LockModeType; +import jakarta.persistence.LockModeType; import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Modifying; diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/PersistenceJPAConfig.java index 4eda4d9274..69067901f1 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/PersistenceJPAConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/PersistenceJPAConfig.java @@ -2,7 +2,7 @@ package com.baeldung.config; import java.util.Properties; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/SpringWebConfig.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/SpringWebConfig.java index 475970d1f0..de51cf3e23 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/SpringWebConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/SpringWebConfig.java @@ -4,14 +4,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration @ComponentScan({ "com.baeldung.web" }) -public class SpringWebConfig extends WebMvcConfigurerAdapter { +public class SpringWebConfig { @Bean public InternalResourceViewResolver viewResolver() { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/StudentJpaConfig.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/StudentJpaConfig.java index 08f37ea806..692daea66d 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/StudentJpaConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/config/StudentJpaConfig.java @@ -2,7 +2,7 @@ package com.baeldung.config; import java.util.Properties; -import javax.persistence.EntityManagerFactory; +import jakarta.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/KVTag.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/KVTag.java index 1fc186f4ce..29be4eb944 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/KVTag.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/KVTag.java @@ -1,6 +1,6 @@ package com.baeldung.inmemory.persistence.model; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class KVTag { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/LocationTag.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/LocationTag.java index b12ad9fbd1..8591bc7543 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/LocationTag.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/LocationTag.java @@ -1,6 +1,6 @@ package com.baeldung.inmemory.persistence.model; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class LocationTag { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyStudent.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyStudent.java index 190740d582..8334cd2453 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyStudent.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyStudent.java @@ -1,6 +1,6 @@ package com.baeldung.inmemory.persistence.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyTag.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyTag.java index 5af898f7df..a320a0e5ab 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyTag.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/ManyTag.java @@ -1,6 +1,6 @@ package com.baeldung.inmemory.persistence.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/SkillTag.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/SkillTag.java index 738b5d0b36..b035164f2e 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/SkillTag.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/SkillTag.java @@ -1,6 +1,6 @@ package com.baeldung.inmemory.persistence.model; -import javax.persistence.Embeddable; +import jakarta.persistence.Embeddable; @Embeddable public class SkillTag { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/Student.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/Student.java index f0e824e165..52cdae82f4 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/Student.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/inmemory/persistence/model/Student.java @@ -2,9 +2,9 @@ package com.baeldung.inmemory.persistence.model; import java.util.ArrayList; import java.util.List; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.ElementCollection; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity public class Student { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/dao/AbstractJpaDAO.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/dao/AbstractJpaDAO.java index b4827cc7e1..b44dbca3fe 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/dao/AbstractJpaDAO.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/dao/AbstractJpaDAO.java @@ -3,8 +3,8 @@ package com.baeldung.persistence.dao; import java.io.Serializable; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; public abstract class AbstractJpaDAO { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Bar.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Bar.java index 5a88ecc6cf..935623945b 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Bar.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Bar.java @@ -3,15 +3,15 @@ package com.baeldung.persistence.model; import java.io.Serializable; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OrderBy; @Entity public class Bar implements Serializable { diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Foo.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Foo.java index 7897bba4e4..7a82c16788 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Foo.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/model/Foo.java @@ -2,7 +2,7 @@ package com.baeldung.persistence.model; import org.hibernate.annotations.CacheConcurrencyStrategy; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; @Entity diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/Possession.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/Possession.java index 6ad6b8e603..f83a1df916 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/Possession.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/Possession.java @@ -1,6 +1,6 @@ package com.baeldung.persistence.multiple.model.user; -import javax.persistence.*; +import jakarta.persistence.*; @Entity @Table(schema = "spring_jpa_user") diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/User.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/User.java index 3ebb1e0156..cc9ae085ad 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/User.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/persistence/multiple/model/user/User.java @@ -1,6 +1,6 @@ package com.baeldung.persistence.multiple.model.user; -import javax.persistence.*; +import jakarta.persistence.*; import java.util.List; @Entity diff --git a/persistence-modules/spring-jpa/src/main/java/com/baeldung/sqlfiles/Country.java b/persistence-modules/spring-jpa/src/main/java/com/baeldung/sqlfiles/Country.java index f2be33adfd..f4a7b0e046 100644 --- a/persistence-modules/spring-jpa/src/main/java/com/baeldung/sqlfiles/Country.java +++ b/persistence-modules/spring-jpa/src/main/java/com/baeldung/sqlfiles/Country.java @@ -1,11 +1,11 @@ package com.baeldung.sqlfiles; -import static javax.persistence.GenerationType.IDENTITY; +import static jakarta.persistence.GenerationType.IDENTITY; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class Country { diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties index ef17910b68..45a9813c2d 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties +++ b/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties @@ -5,7 +5,7 @@ jdbc.user=tutorialuser jdbc.pass=tutorialmy5ql # hibernate.X -hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop hibernate.cache.use_second_level_cache=false diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties index 9a06518238..9da3512c0e 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties +++ b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties @@ -3,7 +3,7 @@ jdbc.url=jdbc:mysql://localhost:3306/myDb jdbc.user=tutorialuser jdbc.pass=tutorialpass -hibernate.dialect=org.hibernate.dialect.MySQL5Dialect +hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop diff --git a/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml index 76a3b61399..4e51f630cb 100644 --- a/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml +++ b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml @@ -6,11 +6,11 @@ com.baeldung.persistence.model.Foo com.baeldung.persistence.model.Bar - - - - - + + + + + diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java index e98c1fa4a6..d0db8ab667 100644 --- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java @@ -17,7 +17,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/InMemoryDBIntegrationTest.java index d8d867792e..a81c982ee5 100644 --- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/InMemoryDBIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/repository/InMemoryDBIntegrationTest.java @@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; import org.springframework.transaction.annotation.Transactional; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.Arrays; import java.util.List; diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java index 66f20a6724..776f33a7d0 100644 --- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java @@ -7,13 +7,13 @@ import static org.junit.Assert.assertThat; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import com.baeldung.config.PersistenceJPAConfig; import com.baeldung.persistence.model.Foo; diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java index 8d1f94edf8..caba654e47 100644 --- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingIntegrationTest.java @@ -2,13 +2,13 @@ package com.baeldung.persistence.service; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; +import jakarta.persistence.TypedQuery; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Root; import com.baeldung.config.PersistenceJPAConfig; import com.baeldung.persistence.model.Bar; diff --git a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java index b19259d9df..6ada2b8309 100644 --- a/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/com/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java @@ -5,9 +5,9 @@ import static org.junit.Assert.assertNull; import java.util.List; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; import com.baeldung.config.PersistenceJPAConfig; import com.baeldung.persistence.model.Foo; diff --git a/pom.xml b/pom.xml index 7c726c1015..a82f898689 100644 --- a/pom.xml +++ b/pom.xml @@ -351,12 +351,10 @@ - gradle-modules/gradle/maven-to-gradle - language-interop libraries-jdk8 @@ -369,6 +367,8 @@ persistence-modules/hibernate-ogm persistence-modules/java-cassandra persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-neo4j + java-nashorn @@ -473,8 +473,6 @@ apache-spark - image-processing - jenkins-modules jhipster-modules @@ -530,12 +528,10 @@ - gradle-modules/gradle/maven-to-gradle - language-interop libraries-jdk8 @@ -547,6 +543,8 @@ persistence-modules/hibernate-ogm persistence-modules/java-cassandra persistence-modules/spring-data-cassandra-reactive + persistence-modules/spring-data-neo4j + java-nashorn @@ -635,8 +633,6 @@ apache-spark - image-processing - jenkins-modules jhipster-modules @@ -670,7 +666,6 @@ - @@ -732,6 +727,9 @@ spring-batch-2 spring-boot-rest spring-drools + spring-cloud-modules/spring-cloud-contract + spring-cloud-modules/spring-cloud-data-flow + spring-cloud-modules/spring-cloud-circuit-breaker spring-exceptions spring-jenkins-pipeline spring-core @@ -780,6 +778,7 @@ custom-pmd data-structures ddd-contexts + jackson-jr jackson-modules jmh deeplearning4j @@ -851,7 +850,6 @@ javax-sound javaxval javaxval-2 - javax-validation-advanced jetbrains jgit jib @@ -868,6 +866,7 @@ libraries-6 libraries-apache-commons + libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io libraries-data-2 @@ -893,7 +892,6 @@ reactor-core rsocket - spring-5 spring-5-webflux @@ -936,6 +934,9 @@ web-modules xml xml-2 + image-processing + language-interop + gradle-modules/gradle/maven-to-gradle @@ -997,6 +998,7 @@ spring-batch-2 spring-boot-rest spring-drools + spring-cloud-modules/spring-cloud-circuit-breaker spring-exceptions spring-jenkins-pipeline spring-core @@ -1117,7 +1119,6 @@ javax-sound javaxval javaxval-2 - javax-validation-advanced jetbrains jgit jib @@ -1133,6 +1134,7 @@ libraries-5 libraries-6 libraries-apache-commons + libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io libraries-data-2 @@ -1159,7 +1161,6 @@ reactor-core rsocket - spring-5 @@ -1202,6 +1203,9 @@ web-modules xml xml-2 + image-processing + language-interop + gradle-modules/gradle/maven-to-gradle @@ -1290,7 +1294,7 @@ 3.12.2 3.0.0 3.19.0 - 1.18.24 + 1.18.28 2.1.214 31.1-jre 3.2.2 diff --git a/quarkus-modules/quarkus-funqy/pom.xml b/quarkus-modules/quarkus-funqy/pom.xml index 39a6151c69..f5ba9d08d8 100644 --- a/quarkus-modules/quarkus-funqy/pom.xml +++ b/quarkus-modules/quarkus-funqy/pom.xml @@ -1,5 +1,6 @@ - - + 4.0.0 diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index d46612393d..0679f33ae7 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -73,8 +73,10 @@ spring-boot-swagger-2 spring-boot-swagger-jwt spring-boot-swagger-keycloak + spring-boot-swagger-springfox spring-boot-testing spring-boot-testing-2 + spring-boot-testing-spock spring-boot-vue spring-boot-actuator spring-boot-data-2 @@ -93,6 +95,7 @@ spring-boot-properties spring-boot-properties-2 spring-boot-properties-3 + spring-boot-properties-4 spring-boot-properties-migrator-demo diff --git a/spring-boot-modules/spring-boot-3-test-pitfalls/pom.xml b/spring-boot-modules/spring-boot-3-test-pitfalls/pom.xml index 21a7e5f702..f3ed67e87b 100644 --- a/spring-boot-modules/spring-boot-3-test-pitfalls/pom.xml +++ b/spring-boot-modules/spring-boot-3-test-pitfalls/pom.xml @@ -83,5 +83,4 @@ 3.0.0-M7 - diff --git a/spring-boot-modules/spring-boot-3-url-matching/pom.xml b/spring-boot-modules/spring-boot-3-url-matching/pom.xml index ca8213e1cf..0ed6fdbd9b 100644 --- a/spring-boot-modules/spring-boot-3-url-matching/pom.xml +++ b/spring-boot-modules/spring-boot-3-url-matching/pom.xml @@ -3,10 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-boot-3 + spring-boot-3-url-matching 0.0.1-SNAPSHOT - spring-boot-3 - URL Matching in Spring Boot + spring-boot-3-url-matching + URL Matching in Spring Boot 3 com.baeldung diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml index bdb23f9fe2..2abce7df76 100644 --- a/spring-boot-modules/spring-boot-aws/pom.xml +++ b/spring-boot-modules/spring-boot-aws/pom.xml @@ -6,8 +6,8 @@ com.baeldung spring-boot-aws 0.0.1-SNAPSHOT - spring-boot-data-3 - spring-boot-boot + spring-boot-aws + spring-boot-aws com.baeldung.spring-boot-modules diff --git a/spring-boot-modules/spring-boot-basic-customization/pom.xml b/spring-boot-modules/spring-boot-basic-customization/pom.xml index 28b30e6bd4..20b2980f29 100644 --- a/spring-boot-modules/spring-boot-basic-customization/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization/pom.xml @@ -39,4 +39,50 @@ com.baeldung.changeport.CustomApplication + + + errorhandling + + com.baeldung.errorhandling.ErrorHandlingApplication + + + + filter + + com.baeldung.bootcustomfilters.SpringBootFiltersApplication + + + + customapplication + + com.baeldung.changeport.CustomApplication + + + + failureanalyzer + + com.baeldung.failureanalyzer.FailureAnalyzerApplication + + + + favicon + + com.baeldung.favicon.FaviconApplication + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 1.5.2.RELEASE + + ${spring.boot.mainclass} + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java index c4653932c0..825e77f0ce 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java @@ -2,13 +2,15 @@ package com.baeldung.bootcustomfilters; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; /** * Boot application * @author hemant * */ -@SpringBootApplication +@Profile("filter") +@SpringBootApplication(scanBasePackages = "com.baeldung.bootcustomfilters.*") public class SpringBootFiltersApplication { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java index 3fce0f1289..b8885393eb 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java @@ -4,8 +4,10 @@ import java.util.Collections; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; -@SpringBootApplication +@Profile("customapplication") +@SpringBootApplication(scanBasePackages = "com.baeldung.changeport") public class CustomApplication { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java index 9f6c209deb..1326c35382 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java @@ -2,7 +2,9 @@ package com.baeldung.errorhandling; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; +@Profile("errorhandling") @SpringBootApplication(scanBasePackages = "com.baeldung.errorhandling") public class ErrorHandlingApplication { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java index d08fa05c6e..4ad763e0ab 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java @@ -2,10 +2,12 @@ package com.baeldung.failureanalyzer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; import javax.annotation.security.RolesAllowed; -@SpringBootApplication +@Profile("failureanalyzer") +@SpringBootApplication(scanBasePackages = "com.baeldung.failureanalyzer") public class FailureAnalyzerApplication { @RolesAllowed("*") public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java index f94549b988..33852db863 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java @@ -2,8 +2,10 @@ package com.baeldung.favicon; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; -@SpringBootApplication +@Profile("favicon") +@SpringBootApplication(scanBasePackages = "com.baeldung.favicon") public class FaviconApplication { public static void main(String[] args) { diff --git a/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java index 2d9fb56217..b59e190418 100644 --- a/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java +++ b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java @@ -1,13 +1,16 @@ package com.baeldung.failureanalyzer; import ch.qos.logback.classic.spi.ILoggingEvent; + import com.baeldung.failureanalyzer.utils.ListAppender; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.SpringApplication; import java.util.Collection; +import java.util.Properties; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -27,7 +30,11 @@ public class FailureAnalyzerAppIntegrationTest { @Test public void givenBeanCreationErrorInContext_whenContextLoaded_thenFailureAnalyzerLogsReport() { try { - SpringApplication.run(FailureAnalyzerApplication.class); + Properties properties = new Properties(); + properties.setProperty("spring.profiles.active", "failureanalyzer"); + SpringApplication app = new SpringApplication(FailureAnalyzerApplication.class); + app.setDefaultProperties(properties); + app.run(); } catch (BeanCreationException e) { Collection allLoggedEntries = ListAppender.getEvents() .stream() diff --git a/spring-boot-modules/spring-boot-keycloak-2/pom.xml b/spring-boot-modules/spring-boot-keycloak-2/pom.xml index c5bb97fb21..4c4f403776 100644 --- a/spring-boot-modules/spring-boot-keycloak-2/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak-2/pom.xml @@ -77,7 +77,6 @@ ${keycloak.version} - diff --git a/spring-boot-modules/spring-boot-libraries-2/pom.xml b/spring-boot-modules/spring-boot-libraries-2/pom.xml index 3cc228d838..1734a7d5ac 100644 --- a/spring-boot-modules/spring-boot-libraries-2/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-2/pom.xml @@ -16,7 +16,7 @@ org.springframework.experimental spring-modulith-bom - 0.5.1 + ${spring-modulith-bom.version} import pom @@ -48,7 +48,7 @@ org.jobrunr jobrunr-spring-boot-starter - ${jobrunr.version} + ${jobrunr-spring-boot-starter.version} @@ -59,7 +59,7 @@ org.openapitools jackson-databind-nullable - ${jackson-databind.version} + ${jackson-databind-nullable.version} org.springdoc @@ -80,23 +80,23 @@ org.reflections reflections - 0.10.2 + ${reflections.version} org.jboss jandex - 2.4.3.Final + ${jandex.version} io.github.resilience4j resilience4j-spring-boot2 - 1.7.0 + ${resilience4j-spring-boot2.version} com.github.tomakehurst wiremock-jre8 - 2.34.0 + ${wiremock-jre8.version} test @@ -141,7 +141,7 @@ org.jboss.jandex jandex-maven-plugin - 1.2.3 + ${jandex-maven-plugin.version} compile @@ -163,11 +163,17 @@ - 3.1.1 + 0.5.1 + 3.1.1 4.0.3 5.3.0 2.4.5 - 0.2.1 + 0.2.1 + 0.10.2 + 2.4.3.Final + 2.0.2 + 2.34.0 + 1.2.3 1.7.0 com.baeldung.openapi.OpenApiApplication diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java index 92d2286518..019d39f590 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java @@ -53,17 +53,17 @@ public class KongAdminAPILiveTest { @Test public void givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong() throws Exception { - restTemplate.delete("http://localhost:8001/apis/stock-api"); + restTemplate.delete("http://localhost:8001/stock-api"); APIObject stockAPI = new APIObject("stock-api", "stock.api", "http://localhost:9090", "/"); HttpEntity apiEntity = new HttpEntity<>(stockAPI); - ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class); + ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001", apiEntity, String.class); assertEquals(HttpStatus.CREATED, addAPIResp.getStatusCode()); - addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class); + addAPIResp = restTemplate.postForEntity("http://localhost:8001", apiEntity, String.class); assertEquals(HttpStatus.CONFLICT, addAPIResp.getStatusCode()); - String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class); + String apiListResp = restTemplate.getForObject("http://localhost:8001/", String.class); assertTrue(apiListResp.contains("stock-api")); @@ -94,17 +94,17 @@ public class KongAdminAPILiveTest { @Test public void givenAPI_whenEnableAuth_thenAnonymousDenied() throws Exception { - String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class); + String apiListResp = restTemplate.getForObject("http://localhost:8001/", String.class); if (!apiListResp.contains("stock-api")) { givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong(); } PluginObject authPlugin = new PluginObject("key-auth"); - ResponseEntity enableAuthResp = restTemplate.postForEntity("http://localhost:8001/apis/stock-api/plugins", new HttpEntity<>(authPlugin), String.class); + ResponseEntity enableAuthResp = restTemplate.postForEntity("http://localhost:8001/stock-api/plugins", new HttpEntity<>(authPlugin), String.class); assertTrue(HttpStatus.CREATED == enableAuthResp.getStatusCode() || HttpStatus.CONFLICT == enableAuthResp.getStatusCode()); - String pluginsResp = restTemplate.getForObject("http://localhost:8001/apis/stock-api/plugins", String.class); + String pluginsResp = restTemplate.getForObject("http://localhost:8001/stock-api/plugins", String.class); assertTrue(pluginsResp.contains("key-auth")); HttpHeaders headers = new HttpHeaders(); @@ -116,7 +116,7 @@ public class KongAdminAPILiveTest { @Test public void givenAPIAuthEnabled_whenAddKey_thenAccessAllowed() throws Exception { - String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class); + String apiListResp = restTemplate.getForObject("http://localhost:8001/", String.class); if (!apiListResp.contains("stock-api")) { givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong(); } @@ -127,7 +127,7 @@ public class KongAdminAPILiveTest { } PluginObject authPlugin = new PluginObject("key-auth"); - ResponseEntity enableAuthResp = restTemplate.postForEntity("http://localhost:8001/apis/stock-api/plugins", new HttpEntity<>(authPlugin), String.class); + ResponseEntity enableAuthResp = restTemplate.postForEntity("http://localhost:8001/stock-api/plugins", new HttpEntity<>(authPlugin), String.class); assertTrue(HttpStatus.CREATED == enableAuthResp.getStatusCode() || HttpStatus.CONFLICT == enableAuthResp.getStatusCode()); final String consumerKey = "eugenp.pass"; @@ -154,14 +154,14 @@ public class KongAdminAPILiveTest { public void givenAdminAPIProxy_whenAddAPIViaProxy_thenAPIAdded() throws Exception { APIObject adminAPI = new APIObject("admin-api", "admin.api", "http://localhost:8001", "/admin-api"); HttpEntity apiEntity = new HttpEntity<>(adminAPI); - ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class); + ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001", apiEntity, String.class); assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode()); HttpHeaders headers = new HttpHeaders(); headers.set("Host", "admin.api"); APIObject baeldungAPI = new APIObject("baeldung-api", "baeldung.com", "http://ww.baeldung.com", "/"); - RequestEntity requestEntity = new RequestEntity<>(baeldungAPI, headers, HttpMethod.POST, new URI("http://localhost:8000/admin-api/apis")); + RequestEntity requestEntity = new RequestEntity<>(baeldungAPI, headers, HttpMethod.POST, new URI("http://localhost:8000/admin-api")); addAPIResp = restTemplate.exchange(requestEntity, String.class); assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode()); diff --git a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java index 7cf67453a6..13e741eb46 100644 --- a/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java +++ b/spring-boot-modules/spring-boot-libraries-2/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java @@ -55,7 +55,7 @@ public class KongLoadBalanceLiveTest { APIObject stockAPI = new APIObject("balanced-stock-api", "balanced.stock.api", "http://stock.api.service", "/"); HttpEntity apiEntity = new HttpEntity<>(stockAPI); - ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class); + ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001", apiEntity, String.class); assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode()); HttpHeaders headers = new HttpHeaders(); diff --git a/spring-boot-modules/spring-boot-mvc-4/pom.xml b/spring-boot-modules/spring-boot-mvc-4/pom.xml index 800ca8e31e..dbbb03ad0e 100644 --- a/spring-boot-modules/spring-boot-mvc-4/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-4/pom.xml @@ -32,11 +32,11 @@ spring-boot-devtools true - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + com.fasterxml.jackson.core jackson-databind diff --git a/spring-boot-modules/spring-boot-mvc-legacy/pom.xml b/spring-boot-modules/spring-boot-mvc-legacy/pom.xml index b5422b12bd..981ba057a8 100644 --- a/spring-boot-modules/spring-boot-mvc-legacy/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-legacy/pom.xml @@ -23,7 +23,7 @@ org.springframework.boot spring-boot-starter-data-jpa - + org.springframework.boot spring-boot-starter-data-rest diff --git a/spring-boot-modules/spring-boot-properties-2/README.md b/spring-boot-modules/spring-boot-properties-2/README.md index 296486e7d7..a10d0db7d3 100644 --- a/spring-boot-modules/spring-boot-properties-2/README.md +++ b/spring-boot-modules/spring-boot-properties-2/README.md @@ -10,4 +10,4 @@ This module contains articles about Properties in Spring Boot. - [Inject Arrays and Lists From Spring Properties Files](https://www.baeldung.com/spring-inject-arrays-lists) - [Inject a Map from a YAML File with Spring](https://www.baeldung.com/spring-yaml-inject-map) - [YAML to List of Objects in Spring Boot](https://www.baeldung.com/spring-boot-yaml-list) -- More articles: [[<-- prev]](../spring-boot-properties) +- More articles: [[<-- Prev]](../spring-boot-properties) [[Next -->]](../spring-boot-properties-3) diff --git a/spring-boot-modules/spring-boot-properties-3/README.md b/spring-boot-modules/spring-boot-properties-3/README.md index 476797965a..f9bae5f12c 100644 --- a/spring-boot-modules/spring-boot-properties-3/README.md +++ b/spring-boot-modules/spring-boot-properties-3/README.md @@ -12,6 +12,4 @@ - [Log Properties in a Spring Boot Application](https://www.baeldung.com/spring-boot-log-properties) - [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) - [Loading Multiple YAML Configuration Files in Spring Boot](https://www.baeldung.com/spring-boot-load-multiple-yaml-configuration-files) -- [Using Environment Variables in Spring Boot’s Properties Files](https://www.baeldung.com/spring-boot-properties-env-variables) -- [Spring Boot Properties Prefix Must Be in Canonical Form](https://www.baeldung.com/spring-boot-properties-canonical-form) -- More articles: [[<-- prev]](../spring-boot-properties-2) +- More articles: [[<-- Prev]](../spring-boot-properties-2) [[Next -->]](../spring-boot-properties-4) diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties index 225ebb05b6..a079837942 100644 --- a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties @@ -26,18 +26,4 @@ spring.config.activate.on-profile=multidocument-prod spring.datasource.password=password spring.datasource.url=jdbc:h2:prod spring.datasource.username=prodUser -bael.property=prodValue -#--- -environment.name=${OS} -java.home.and.environment=${JAVA_HOME}+${OS} -not.existing.system.property=${thispropertydoesnotexist} -baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME} -#--- -#camelCasing -#customProperties.name="Baeldung" -#PascalCasing -#CustomProperties.name="Baeldung" -#SnakingCasing -#custom_properties.name="Baeldung" -#KebabCasing -custom-properties.name="Baeldung" \ No newline at end of file +bael.property=prodValue \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-4/README.md b/spring-boot-modules/spring-boot-properties-4/README.md new file mode 100644 index 0000000000..3033b8725c --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-4/README.md @@ -0,0 +1,10 @@ + +## Spring Boot Properties + + + +### Relevant Articles: + +- [Using Environment Variables in Spring Boot’s Properties Files](https://www.baeldung.com/spring-boot-properties-env-variables) +- [Spring Boot Properties Prefix Must Be in Canonical Form](https://www.baeldung.com/spring-boot-properties-canonical-form) +- More articles: [[<-- Prev]](../spring-boot-properties-3) diff --git a/spring-boot-modules/spring-boot-properties-4/pom.xml b/spring-boot-modules/spring-boot-properties-4/pom.xml new file mode 100644 index 0000000000..1699e2defd --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-4/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + spring-boot-properties-4 + 0.0.1-SNAPSHOT + spring-boot-properties-4 + Spring Boot Properties Module + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/BaeldungProperties.java b/spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/envvariables/BaeldungProperties.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/BaeldungProperties.java rename to spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/envvariables/BaeldungProperties.java diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/MyController.java b/spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/envvariables/MyController.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/envvariables/MyController.java rename to spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/envvariables/MyController.java diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java b/spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java rename to spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/error/KebabCasingDemoApplication.java diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/configuration/MainConfiguration.java b/spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/error/configuration/MainConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-3/src/main/java/com/baeldung/error/configuration/MainConfiguration.java rename to spring-boot-modules/spring-boot-properties-4/src/main/java/com/baeldung/error/configuration/MainConfiguration.java diff --git a/spring-boot-modules/spring-boot-properties-4/src/main/resources/application.properties b/spring-boot-modules/spring-boot-properties-4/src/main/resources/application.properties new file mode 100644 index 0000000000..a078e68820 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-4/src/main/resources/application.properties @@ -0,0 +1,13 @@ +environment.name=${OS} +java.home.and.environment=${JAVA_HOME}+${OS} +not.existing.system.property=${thispropertydoesnotexist} +baeldung.presentation=${HELLO_BAELDUNG}. Java is installed in the folder: ${JAVA_HOME} +#--- +#camelCasing +#customProperties.name="Baeldung" +#PascalCasing +#CustomProperties.name="Baeldung" +#SnakingCasing +#custom_properties.name="Baeldung" +#KebabCasing +custom-properties.name="Baeldung" \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java b/spring-boot-modules/spring-boot-properties-4/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-properties-4/src/test/java/com/baeldung/envvariables/MyControllerIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-redis/pom.xml b/spring-boot-modules/spring-boot-redis/pom.xml index 4467e38dbe..e0ae5d388f 100644 --- a/spring-boot-modules/spring-boot-redis/pom.xml +++ b/spring-boot-modules/spring-boot-redis/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 com.baelding diff --git a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/config/RedisConfiguration.java b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/config/RedisConfiguration.java index 2c050af8af..896339646b 100644 --- a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/config/RedisConfiguration.java +++ b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/config/RedisConfiguration.java @@ -2,7 +2,6 @@ package com.baelding.springbootredis.config; import com.baelding.springbootredis.model.Session; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; diff --git a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/controller/SessionController.java b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/controller/SessionController.java index 156ca0195f..020de31019 100644 --- a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/controller/SessionController.java +++ b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/controller/SessionController.java @@ -6,7 +6,6 @@ import com.baelding.springbootredis.service.cache.session.SessionCache; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; diff --git a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/model/Session.java b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/model/Session.java index 5c9d26147e..b9c8668104 100644 --- a/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/model/Session.java +++ b/spring-boot-modules/spring-boot-redis/src/main/java/com/baelding/springbootredis/model/Session.java @@ -1,19 +1,25 @@ package com.baelding.springbootredis.model; import lombok.Builder; -import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Data; +import lombok.NoArgsConstructor; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.TimeToLive; -@Data @Builder @EqualsAndHashCode @RedisHash(timeToLive = 60L) +@Data +@NoArgsConstructor public class Session { @Id private String id; @TimeToLive private Long expirationInSeconds; + public Session(String id, Long expirationInSeconds) { + this.id = id; + this.expirationInSeconds = expirationInSeconds; + } } diff --git a/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/SpringBootRedisApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/SpringBootRedisApplicationIntegrationTest.java index 69c88706e4..d1ee5ad68a 100644 --- a/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/SpringBootRedisApplicationIntegrationTest.java +++ b/spring-boot-modules/spring-boot-redis/src/test/java/com/baelding/springbootredis/SpringBootRedisApplicationIntegrationTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpHeaders; import org.springframework.test.web.reactive.server.WebTestClient; @@ -19,6 +20,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RedisTestConfiguration.class) +@AutoConfigureMockMvc class SpringBootRedisApplicationIntegrationTest { private static final String V1_SESSIONS_ENDPOINT = "/v1/sessions"; diff --git a/spring-boot-modules/spring-boot-springdoc-2/README.md b/spring-boot-modules/spring-boot-springdoc-2/README.md new file mode 100644 index 0000000000..80977ae5d5 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Documenting a Spring REST API Using OpenAPI 3.0](https://www.baeldung.com/spring-rest-openapi-documentation) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/pom.xml b/spring-boot-modules/spring-boot-springdoc-2/pom.xml new file mode 100644 index 0000000000..1ea52667c5 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/pom.xml @@ -0,0 +1,119 @@ + + + 4.0.0 + spring-boot-springdoc-2 + 0.0.1-SNAPSHOT + spring-boot-springdoc-2 + jar + Project for Springdoc integration + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc.version} + + + org.springdoc + springdoc-openapi-starter-common + ${springdoc.version} + + + org.jetbrains.kotlin + kotlin-stdlib + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + integration + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + pre-integration-test + + start + + + + post-integration-test + + stop + + + + + + org.springdoc + springdoc-openapi-maven-plugin + ${springdoc-openapi-maven-plugin.version} + + + integration-test + + generate + + + + + http://localhost:8080/api-docs + openapi.json + ${project.build.directory} + + + + + + + + + 2.1.0 + 1.4 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/SpringdocApplication.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/SpringdocApplication.java new file mode 100644 index 0000000000..45c7c23621 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/SpringdocApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springdoc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringdocApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringdocApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/BookController.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/BookController.java new file mode 100644 index 0000000000..790cc0797e --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/BookController.java @@ -0,0 +1,83 @@ +package com.baeldung.springdoc.controller; + +import com.baeldung.springdoc.exception.BookNotFoundException; +import com.baeldung.springdoc.model.Book; +import com.baeldung.springdoc.repository.BookRepository; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.Collection; + +@RestController +@RequestMapping("/api/book") +public class BookController { + + private final BookRepository repository; + + public BookController(BookRepository repository) { + this.repository = repository; + } + + @Operation(summary = "Get a book by its id") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Found the book", + content = {@Content(mediaType = "application/json", schema = @Schema(implementation = Book.class))}), + @ApiResponse(responseCode = "400", description = "Invalid id supplied", content = @Content), + @ApiResponse(responseCode = "404", description = "Book not found", content = @Content)}) // @formatter:on + @GetMapping("/{id}") + public Book findById(@Parameter(description = "id of book to be searched") @PathVariable long id) { + return repository.findById(id) + .orElseThrow(BookNotFoundException::new); + } + + @GetMapping("/") + public Collection findBooks() { + return repository.getBooks(); + } + + @GetMapping("/filter") + public Page filterBooks(@ParameterObject Pageable pageable) { + return repository.getBooks(pageable); + } + + @PutMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public Book updateBook(@PathVariable("id") final String id, @RequestBody final Book book) { + return book; + } + + @PatchMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public Book patchBook(@PathVariable("id") final String id, @RequestBody final Book book) { + return book; + } + + @PostMapping("/") + @ResponseStatus(HttpStatus.CREATED) + public Book postBook(@NotNull @Valid @RequestBody final Book book) { + return book; + } + + @RequestMapping(method = RequestMethod.HEAD, value = "/") + @ResponseStatus(HttpStatus.OK) + public Book headBook() { + return new Book(); + } + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.OK) + public long deleteBook(@PathVariable final long id) { + return id; + } +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java new file mode 100644 index 0000000000..c17cebf37b --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java @@ -0,0 +1,30 @@ +package com.baeldung.springdoc.controller; + +import io.swagger.v3.oas.annotations.Hidden; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDate; +import java.time.LocalTime; + +@Hidden +@RestController +public class RegularRestController { + + @Hidden + @GetMapping("/getAuthor") + public String getAuthor() { + return "Umang Budhwar"; + } + + @GetMapping("/getDate") + public LocalDate getDate() { + return LocalDate.now(); + } + + @GetMapping("/getTime") + public LocalTime getTime() { + return LocalTime.now(); + } + +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java new file mode 100644 index 0000000000..331f663548 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java @@ -0,0 +1,5 @@ +package com.baeldung.springdoc.exception; + +public class BookNotFoundException extends RuntimeException { + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java new file mode 100644 index 0000000000..0a1cbd5d35 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java @@ -0,0 +1,24 @@ +package com.baeldung.springdoc.exception; + +import org.springframework.core.convert.ConversionFailedException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class GlobalControllerExceptionHandler { + + @ExceptionHandler(ConversionFailedException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleConversion(RuntimeException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(BookNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ResponseEntity handleBookNotFound(RuntimeException ex) { + return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND); + } +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/Foo.kt b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/Foo.kt new file mode 100644 index 0000000000..08af8fddc6 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/Foo.kt @@ -0,0 +1,16 @@ +package com.baeldung.springdoc.kotlin + +import jakarta.persistence.Entity +import jakarta.persistence.Id +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size + +@Entity +data class Foo( + @Id + val id: Long = 0, + + @NotBlank + @Size(min = 0, max = 50) + val name: String = "" +) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/FooController.kt b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/FooController.kt new file mode 100644 index 0000000000..953cf6d00e --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/kotlin/FooController.kt @@ -0,0 +1,36 @@ +package com.baeldung.springdoc.kotlin + +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.ArraySchema +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.responses.ApiResponses +import org.hibernate.internal.util.collections.CollectionHelper.listOf +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/") +class FooController { + val fooList: List = listOf(Foo(1, "one"), Foo(2, "two")) + + @Operation(summary = "Get all foos") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", description = "Found Foos", content = [ + (Content( + mediaType = "application/json", array = ( + ArraySchema(schema = Schema(implementation = Foo::class))) + ))] + ), + ApiResponse(responseCode = "400", description = "Bad request", content = [Content()]), + ApiResponse(responseCode = "404", description = "Did not find any Foos", content = [Content()])] + ) + @GetMapping("/foo") + fun getAllFoos(): List = fooList +} + + diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/model/Book.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/model/Book.java new file mode 100644 index 0000000000..7b378a5183 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/model/Book.java @@ -0,0 +1,42 @@ +package com.baeldung.springdoc.model; + + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public class Book { + + private long id; + + @NotBlank + @Size(min = 0, max = 20) + private String title; + + @NotBlank + @Size(min = 0, max = 30) + private String author; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/repository/BookRepository.java b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/repository/BookRepository.java new file mode 100644 index 0000000000..51247910b8 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/java/com/baeldung/springdoc/repository/BookRepository.java @@ -0,0 +1,34 @@ +package com.baeldung.springdoc.repository; + +import com.baeldung.springdoc.model.Book; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +import java.util.*; + +@Repository +public class BookRepository { + + private final Map books = new HashMap<>(); + + public Optional findById(long id) { + return Optional.ofNullable(books.get(id)); + } + + public void add(Book book) { + books.put(book.getId(), book); + } + + public Collection getBooks() { + return books.values(); + } + + public Page getBooks(Pageable pageable) { + int toSkip = pageable.getPageSize() * pageable.getPageNumber(); + List result = books.values().stream().skip(toSkip).limit(pageable.getPageSize()).toList(); + + return new PageImpl<>(result, pageable, books.size()); + } +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/application.properties new file mode 100644 index 0000000000..a668601a7d --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/application.properties @@ -0,0 +1,24 @@ +# custom path for swagger-ui +springdoc.swagger-ui.path=/swagger-ui-custom.html + +# custom path for api docs +springdoc.api-docs.path=/api-docs + +# H2 Related Configurations +spring.datasource.url=jdbc:h2:mem:springdoc + +## for com.baeldung.restdocopenapi ## +springdoc.version=@springdoc.version@ +spring.jpa.hibernate.ddl-auto=none + +## for com.baeldung.jwt ## +jwt.private.key=classpath:app.key +jwt.public.key=classpath:app.pub + + +api.version=1.0-SNAPSHOT +tos.uri=terms-of-service +api.server.url=https://www.baeldung.com +api.description=The User API is used to create, update, and delete users. Users can be created with or without an associated account. If an account is created, the user will be granted the ROLE_USER role. If an account is not created, the user will be granted the ROLE_USER role. +springdoc.swagger-ui.operationsSorter=alpha +springdoc.swagger-ui.tagsSorter=alpha \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/data.sql b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/data.sql new file mode 100644 index 0000000000..f80e53b717 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/data.sql @@ -0,0 +1,4 @@ +INSERT INTO Foo(id, title, body) VALUES (1, 'Foo 1', 'Foo body 1'); +INSERT INTO Foo(id, title, body) VALUES (2, 'Foo 2', 'Foo body 2'); +INSERT INTO Foo(id, title, body) VALUES (3, 'Foo 3', 'Foo body 3'); + diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..73dd672c1a --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/schema.sql b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/schema.sql new file mode 100644 index 0000000000..e5d33da019 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/main/resources/schema.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS foo; + +CREATE TABLE foo ( + id INTEGER NOT NULL AUTO_INCREMENT, + title VARCHAR(250) NOT NULL, + body VARCHAR(250), + PRIMARY KEY (id) +); \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/test/java/com/baeldung/springdoc/SpringContextTest.java b/spring-boot-modules/spring-boot-springdoc-2/src/test/java/com/baeldung/springdoc/SpringContextTest.java new file mode 100644 index 0000000000..d7cd6bc30b --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/test/java/com/baeldung/springdoc/SpringContextTest.java @@ -0,0 +1,17 @@ +package com.baeldung.springdoc; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +class SpringContextTest { + + @Test + void whenSpringContextIsBootstrapped_thenNoExceptions() { + + } + +} diff --git a/spring-boot-modules/spring-boot-springdoc-2/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-springdoc-2/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..ab4a5f3a20 --- /dev/null +++ b/spring-boot-modules/spring-boot-springdoc-2/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + [%d{ISO8601}]-[%thread] %-5level %logger - %msg%n + + + + + + + diff --git a/spring-boot-modules/spring-boot-springdoc/README.md b/spring-boot-modules/spring-boot-springdoc/README.md index 3d0fd19ab1..95e6bf6ead 100644 --- a/spring-boot-modules/spring-boot-springdoc/README.md +++ b/spring-boot-modules/spring-boot-springdoc/README.md @@ -1,6 +1,5 @@ ### Relevant Articles: -- [Documenting a Spring REST API Using OpenAPI 3.0](https://www.baeldung.com/spring-rest-openapi-documentation) - [Spring REST Docs vs OpenAPI](https://www.baeldung.com/spring-rest-docs-vs-openapi) - [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) - [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated) diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml index e21efc35d2..8ed9b7c22b 100644 --- a/spring-boot-modules/spring-boot-springdoc/pom.xml +++ b/spring-boot-modules/spring-boot-springdoc/pom.xml @@ -45,7 +45,7 @@ spring-boot-starter-test test - + org.springdoc springdoc-openapi-ui @@ -61,7 +61,6 @@ springdoc-openapi-security ${springdoc.version} - org.springframework.restdocs spring-restdocs-mockmvc @@ -119,53 +118,6 @@ - - - integration - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - pre-integration-test - - start - - - - post-integration-test - - stop - - - - - - org.springdoc - springdoc-openapi-maven-plugin - ${springdoc-openapi-maven-plugin.version} - - - integration-test - - generate - - - - - http://localhost:8080/api-docs - openapi.json - ${project.build.directory} - - - - - - - 1.7.0 1.5.6 diff --git a/spring-boot-modules/spring-boot-swagger-2/README.md b/spring-boot-modules/spring-boot-swagger-2/README.md index 99e4c4cca5..512ed9e52c 100644 --- a/spring-boot-modules/spring-boot-swagger-2/README.md +++ b/spring-boot-modules/spring-boot-swagger-2/README.md @@ -2,7 +2,6 @@ - [Swagger: Specify Two Responses with the Same Response Code](https://www.baeldung.com/swagger-two-responses-one-response-code) - [Specify an Array of Strings as Body Parameters in Swagger](https://www.baeldung.com/swagger-body-array-of-strings) -- [Swagger @ApiParam vs @ApiModelProperty](https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty) +- [Swagger @Parameter vs @Schema](https://www.baeldung.com/swagger-parameter-vs-schema) - [Map Date Types With OpenAPI Generator](https://www.baeldung.com/openapi-map-date-types) - [API First Development with Spring Boot and OpenAPI 3.0](https://www.baeldung.com/spring-boot-openapi-api-first-development) -- [Change Swagger-UI URL prefix](https://www.baeldung.com/spring-boot-custom-swagger-url) diff --git a/spring-boot-modules/spring-boot-swagger-2/pom.xml b/spring-boot-modules/spring-boot-swagger-2/pom.xml index daca41426a..12b9bf664b 100644 --- a/spring-boot-modules/spring-boot-swagger-2/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-2/pom.xml @@ -34,11 +34,6 @@ springfox-oas ${springfox.version} - - io.springfox - springfox-swagger-ui - ${springfox.version} - javax.validation validation-api @@ -48,11 +43,6 @@ springfox-swagger2 ${springfox.version} - - io.springfox - springfox-spring-webmvc - ${springfox.version} - diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java index d4a7774510..2e5e4f8ce5 100644 --- a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/config/Swagger2Config.java @@ -4,35 +4,20 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; @Configuration @EnableWebMvc -@EnableSwagger2 public class Swagger2Config { - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build() - .apiInfo(apiEndPointsInfo()); - } - private ApiInfo apiEndPointsInfo() { - return new ApiInfoBuilder().title("Swagger Array") + @Bean + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("Swagger Array") .description("This is a sample Swagger description for an Array server") - .license("Apache 2.0") - .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .version("1.0.0") - .build(); + .license(new License().name("Apache 2.0") + .url("http://www.apache.org/licenses/LICENSE-2.0.html"))); } } \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java index 5edf610154..8bd421241c 100644 --- a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/FooController.java @@ -12,8 +12,8 @@ import org.springframework.web.bind.annotation.ResponseStatus; import com.baeldung.swagger2bootmvc.model.Foo; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; @Controller public class FooController { @@ -26,7 +26,7 @@ public class FooController { @RequestMapping(method = RequestMethod.POST, value = "/foos") @ResponseStatus(HttpStatus.CREATED) @ResponseBody - @ApiImplicitParams({ @ApiImplicitParam(name = "foo", value = "List of strings", paramType = "body", dataType = "Foo") }) + @Parameters({ @Parameter(name = "foo", description = "List of strings") }) public Foo create(@RequestBody final Foo foo) { foo.setId(Long.parseLong(randomNumeric(2))); return foo; diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java index fa879f3bea..727b6e21b0 100644 --- a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/controller/UserController.java @@ -10,27 +10,26 @@ import org.springframework.web.bind.annotation.ResponseStatus; import com.baeldung.swagger2bootmvc.model.User; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; @Controller public class UserController { public UserController() { super(); - } //@formatter:off + } @RequestMapping(method = RequestMethod.POST, value = "/createUser", produces = "application/json; charset=UTF-8") @ResponseStatus(HttpStatus.CREATED) @ResponseBody - @ApiOperation(value = "Create user", - notes = "This method creates a new user") - public User createUser(@ApiParam( + @Operation(summary = "Create user", + description = "This method creates a new user") + public User createUser(@Parameter( name = "firstName", - type = "String", - value = "First Name of the user", + description = "First Name of the user", example = "Vatsal", - required = true) @RequestParam String firstName) { //@formatter:on + required = true) @RequestParam String firstName) { User user = new User(firstName); return user; } diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java index f3fe56e07d..c8eadadb26 100644 --- a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/Foo.java @@ -2,14 +2,13 @@ package com.baeldung.swagger2bootmvc.model; import java.util.List; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class Foo { private long id; - @ApiModelProperty(name = "name", dataType = "List", example = "[\"str1\", \"str2\", \"str3\"]") + @Schema(name = "name", type = "array", example = "[\"str1\", \"str2\", \"str3\"]") private List name; public Foo() { diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java index b4ec55f564..1b63ffc81d 100644 --- a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java +++ b/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/swagger2bootmvc/model/User.java @@ -1,12 +1,11 @@ package com.baeldung.swagger2bootmvc.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class User { - @ApiModelProperty(value = "first name of the user", name = "firstName", dataType = "String", example = "Vatsal") + @Schema(description = "first name of the user", name = "firstName", type = "string", example = "Vatsal") String firstName; public User() { diff --git a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml index e0d96627cd..464777a788 100644 --- a/spring-boot-modules/spring-boot-swagger-jwt/pom.xml +++ b/spring-boot-modules/spring-boot-swagger-jwt/pom.xml @@ -21,9 +21,9 @@ spring-boot-starter-web - io.springfox - springfox-boot-starter - ${springfox.version} + org.springdoc + springdoc-openapi-ui + ${springdoc.version} @@ -37,7 +37,7 @@ - 3.0.0 + 1.7.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/configuration/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/configuration/SwaggerConfiguration.java index e5e87de3ec..f67b75c670 100644 --- a/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/configuration/SwaggerConfiguration.java +++ b/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/configuration/SwaggerConfiguration.java @@ -3,54 +3,32 @@ package com.baeldung.swaggerjwt.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.*; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; @Configuration public class SwaggerConfiguration { - public static final String AUTHORIZATION_HEADER = "Authorization"; - - private ApiInfo apiInfo() { - return new ApiInfo("My REST API", "Some custom description of API.", "1.0", "Terms of service", new Contact("Sallo Szrajbman", "www.baeldung.com", "salloszraj@gmail.com"), "License of API", "API license URL", Collections.emptyList()); - } - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) - .securityContexts(Arrays.asList(securityContext())) - .securitySchemes(Arrays.asList(apiKey())) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); + public OpenAPI openAPI() { + return new OpenAPI().addSecurityItem(new SecurityRequirement().addList("Bearer Authentication")) + .components(new Components().addSecuritySchemes("Bearer Authentication", createAPIKeyScheme())) + .info(new Info().title("My REST API") + .description("Some custom description of API.") + .version("1.0").contact(new Contact().name("Sallo Szrajbman").email( "www.baeldung.com").url("salloszraj@gmail.com")) + .license(new License().name("License of API") + .url("API license URL"))); } - private ApiKey apiKey() { - return new ApiKey("JWT", AUTHORIZATION_HEADER, "header"); - } - - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(List.of(defaultAuth())) - .operationSelector(o -> o.requestMappingPattern() - .matches("/.*")) - .build(); - } - - private SecurityReference defaultAuth() { - return SecurityReference.builder() - .scopes(new AuthorizationScope[0]) - .reference("JWT") - .build(); + private SecurityScheme createAPIKeyScheme() { + return new SecurityScheme().type(SecurityScheme.Type.HTTP) + .bearerFormat("JWT") + .scheme("bearer"); } } diff --git a/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/controller/ClientsRestController.java b/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/controller/ClientsRestController.java index f60ba2448a..1e73ed55be 100644 --- a/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/controller/ClientsRestController.java +++ b/spring-boot-modules/spring-boot-swagger-jwt/src/main/java/com/baeldung/swaggerjwt/controller/ClientsRestController.java @@ -3,20 +3,17 @@ package com.baeldung.swaggerjwt.controller; import java.util.Arrays; import java.util.List; -import com.baeldung.swaggerjwt.configuration.SwaggerConfiguration; -import io.swagger.annotations.Api; -import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; @RestController(value = "/clients") -@Api( tags = "Clients") +@Tag(name = "Clients") public class ClientsRestController { - @ApiOperation(value = "This method is used to get the clients.") + @Operation(summary = "This method is used to get the clients.") @GetMapping public List getClients() { return Arrays.asList("First Client", "Second Client"); diff --git a/spring-boot-modules/spring-boot-swagger-springfox/README.md b/spring-boot-modules/spring-boot-swagger-springfox/README.md new file mode 100644 index 0000000000..301b2752ee --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/README.md @@ -0,0 +1,7 @@ +## Relevant Articles: + +- [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) +- [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated) +- [Remove Basic Error Controller In SpringFox Swagger-UI](https://www.baeldung.com/spring-swagger-remove-error-controller) +- [Change Swagger-UI URL prefix](https://www.baeldung.com/spring-boot-custom-swagger-url) +- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-springfox/pom.xml b/spring-boot-modules/spring-boot-swagger-springfox/pom.xml new file mode 100644 index 0000000000..a856253f07 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + spring-boot-swagger-springfox + 0.1.0-SNAPSHOT + spring-boot-swagger-springfox + jar + Module For Spring Boot Swagger Springfox + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + io.springfox + springfox-boot-starter + ${springfox.version} + + + com.google.guava + guava + ${guava.version} + + + + + 3.0.0 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/Application.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/Application.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/Application.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/Application.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/config/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/config/SwaggerConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/config/SwaggerConfiguration.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/config/SwaggerConfiguration.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/controller/BookController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/controller/BookController.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/apiswagger/controller/BookController.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/apiswagger/controller/BookController.java diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/springdoc/demo/SpringFoxExampleApplication.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/SpringFoxExampleApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/springdoc/demo/SpringFoxExampleApplication.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/SpringFoxExampleApplication.java diff --git a/spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/springdoc/demo/config/SpringFoxSwaggerConfig.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/config/SpringFoxSwaggerConfig.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger-2/src/main/java/com/baeldung/springdoc/demo/config/SpringFoxSwaggerConfig.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/config/SpringFoxSwaggerConfig.java diff --git a/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/SwaggerController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/SwaggerController.java new file mode 100644 index 0000000000..79c35e025e --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/SwaggerController.java @@ -0,0 +1,13 @@ +package com.baeldung.springdoc.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class SwaggerController { + + @RequestMapping("/myproject") + public String getRedirectUrl() { + return "redirect:swagger-ui.html"; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/TopicsController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/TopicsController.java new file mode 100644 index 0000000000..dee825788d --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/controller/TopicsController.java @@ -0,0 +1,26 @@ +package com.baeldung.springdoc.demo.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.springdoc.demo.model.Topic; +import com.baeldung.springdoc.demo.service.TopicService; + + +@RestController +public class TopicsController { + + @Autowired + TopicService topicService; + + @GetMapping(value = "/topics") + public ResponseEntity> getAllTopics() { + return new ResponseEntity<>(topicService.getAlllTopics(), HttpStatus.OK); + } +} diff --git a/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/model/Topic.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/model/Topic.java new file mode 100644 index 0000000000..0e4417b64f --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/model/Topic.java @@ -0,0 +1,26 @@ +package com.baeldung.springdoc.demo.model; + +public class Topic { + + Integer id; + String name; + + public Topic(Integer id, String name) { + super(); + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/service/TopicService.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/service/TopicService.java new file mode 100644 index 0000000000..a468d2915b --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/springdoc/demo/service/TopicService.java @@ -0,0 +1,26 @@ +package com.baeldung.springdoc.demo.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.baeldung.springdoc.demo.model.Topic; + +@Service +public class TopicService { + + private List topicsList; + + public TopicService(){ + this.topicsList = new ArrayList() {{ + add(new Topic(1, "Topic1")); + add(new Topic(2, "Topic2")); + add(new Topic(3, "Topic3")); + }}; + } + + public List getAlllTopics(){ + return topicsList; + } +} diff --git a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/swagger2/SwaggerConfig.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2/SwaggerConfig.java similarity index 100% rename from spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/swagger2/SwaggerConfig.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2/SwaggerConfig.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/SpringBootSwaggerApplication.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/configuration/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/configuration/SwaggerConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/configuration/SwaggerConfiguration.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/configuration/SwaggerConfiguration.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/controller/RegularRestController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/controller/RegularRestController.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swagger2boot/controller/RegularRestController.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swagger2boot/controller/RegularRestController.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java diff --git a/spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/web/controller/CustomController.java b/spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/web/controller/CustomController.java similarity index 100% rename from spring-security-modules/spring-security-web-rest/src/main/java/com/baeldung/web/controller/CustomController.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/main/java/com/baeldung/web/controller/CustomController.java diff --git a/spring-boot-modules/spring-boot-swagger-springfox/src/main/resources/application.properties b/spring-boot-modules/spring-boot-swagger-springfox/src/main/resources/application.properties new file mode 100644 index 0000000000..a4e98652bc --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java b/spring-boot-modules/spring-boot-swagger-springfox/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java similarity index 100% rename from spring-boot-modules/spring-boot-swagger/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java diff --git a/spring-security-modules/spring-security-web-rest/src/test/java/com/baeldung/web/SwaggerLiveTest.java b/spring-boot-modules/spring-boot-swagger-springfox/src/test/java/com/baeldung/web/SwaggerLiveTest.java similarity index 83% rename from spring-security-modules/spring-security-web-rest/src/test/java/com/baeldung/web/SwaggerLiveTest.java rename to spring-boot-modules/spring-boot-swagger-springfox/src/test/java/com/baeldung/web/SwaggerLiveTest.java index 3f86b63503..4dec4acaa5 100644 --- a/spring-security-modules/spring-security-web-rest/src/test/java/com/baeldung/web/SwaggerLiveTest.java +++ b/spring-boot-modules/spring-boot-swagger-springfox/src/test/java/com/baeldung/web/SwaggerLiveTest.java @@ -4,8 +4,8 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.jayway.restassured.RestAssured; -import com.jayway.restassured.response.Response; +import io.restassured.RestAssured; +import io.restassured.response.Response; public class SwaggerLiveTest { private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest/api"; diff --git a/spring-boot-modules/spring-boot-swagger/README.md b/spring-boot-modules/spring-boot-swagger/README.md index c3f6578dee..75fb450120 100644 --- a/spring-boot-modules/spring-boot-swagger/README.md +++ b/spring-boot-modules/spring-boot-swagger/README.md @@ -1,9 +1,6 @@ ## Relevant Articles: -- [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) -- [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated) - [Generate PDF from Swagger API Documentation](https://www.baeldung.com/swagger-generate-pdf) -- [Remove Basic Error Controller In SpringFox Swagger-UI](https://www.baeldung.com/spring-swagger-remove-error-controller) - [Setting Example and Description with Swagger](https://www.baeldung.com/swagger-set-example-description) - [Document Enum in Swagger](https://www.baeldung.com/swagger-enum) -- [@ApiOperation vs @ApiResponse in Swagger](https://www.baeldung.com/swagger-apioperation-vs-apiresponse) +- [@Operation vs @ApiResponse in Swagger](https://www.baeldung.com/swagger-operation-vs-apiresponse) diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index 749442c225..668c9d561f 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -20,16 +20,16 @@ org.springframework.boot spring-boot-starter-web - - io.springfox - springfox-boot-starter - ${springfox.version} - com.github.kongchen swagger-maven-plugin ${swagger-maven-plugin.version} + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + @@ -80,8 +80,8 @@ - 3.0.0 3.1.1 + 1.7.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java index 32dbe87bae..df808a214b 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java @@ -2,37 +2,26 @@ package com.baeldung.swaggerexample.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; - import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import java.util.Collections; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; @Configuration @EnableWebMvc public class SwaggerConfig { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) - .select() - .apis(RequestHandlerSelectors.basePackage("com.baeldung.swaggerexample")) - .paths(PathSelectors.any()) - .build(); - } - - private ApiInfo apiInfo() { - return new ApiInfo( - "Products API", - "API to let you add and view product", - "0.0.1", - "Terms of service", - new Contact("John Doe", "www.example.com", "myemail@company.com"), - "License of API", "API license URL", Collections.emptyList()); + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("Products API") + .description("API to let you add and view product") + .version("0.0.1") + .contact(new Contact().name("John Doe") + .email("myemail@company.com") + .url("www.example.com")) + .license(new License().name("License of API") + .url("API license URL"))); } } diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java index 7500c01bc0..1e838bc5c9 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java @@ -1,33 +1,41 @@ package com.baeldung.swaggerexample.controller; -import com.baeldung.swaggerexample.entity.Product; -import io.swagger.annotations.*; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.swaggerexample.entity.Product; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; @RestController -@ApiOperation("Products API") +@Tag(name = "Products API") public class ProductController { - @ApiOperation(value = "Create a new product", notes = "Creates a new product as per the request body") + @Operation(summary = "Create a new product", description = "Creates a new product as per the request body") @ApiResponses(value = { - @ApiResponse(code = 201, message = "Successfully created"), - @ApiResponse(code = 400, message = "Bad request - The product is not valid"), - @ApiResponse(code = 500, message = "Internal server error - Something went wrong") + @ApiResponse(responseCode = "201", description = "Successfully created"), @ApiResponse(responseCode = "400", description = "Bad request - The product is not valid"), + @ApiResponse(responseCode = "500", description = "Internal server error - Something went wrong") }) @PostMapping(value = "/products") public ResponseEntity createProduct(@RequestBody Product product) { return new ResponseEntity<>(HttpStatus.CREATED); } - @ApiOperation(value = "Get a product by id", notes = "Returns a product as per the id") + @Operation(summary = "Get a product by id", description = "Returns a product as per the id") @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfully retrieved"), - @ApiResponse(code = 404, message = "Not found - The product was not found") + @ApiResponse(responseCode = "200", description = "Successfully retrieved"), @ApiResponse(responseCode = "404", description = "Not found - The product was not found") }) @GetMapping("/products/{id}") - public ResponseEntity getProduct(@PathVariable("id") @ApiParam(name = "id", value = "Product id", example = "1") Long id) { + public ResponseEntity getProduct(@PathVariable("id") @Parameter(name = "id", description = "Product id", example = "1") Long id) { //retrieval logic return ResponseEntity.ok(new Product(1, "Product 1", "$21.99")); } diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java index 122addadd5..40cde738ab 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java @@ -1,15 +1,15 @@ package com.baeldung.swaggerexample.entity; -import io.swagger.annotations.ApiModelProperty; - +import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; public class Product implements Serializable { - @ApiModelProperty(notes = "Product ID", example = "1", required = true) + + @Schema(name = "Product ID", example = "1", required = true) private Long id; - @ApiModelProperty(notes = "Product name", example = "Product 1", required = false) + @Schema(name = "Product name", example = "Product 1", required = false) private String name; - @ApiModelProperty(notes = "Product price", example = "$100.00", required = true) + @Schema(name = "Product price", example = "$100.00", required = true) private String price; // constructor and getter/setters diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/config/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/config/SwaggerConfiguration.java index 5a4d237d97..33e7e64b19 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/config/SwaggerConfiguration.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/config/SwaggerConfiguration.java @@ -2,21 +2,20 @@ package com.baeldung.swaggerresponses.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; @Configuration +@EnableWebMvc public class SwaggerConfiguration { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("Swagger Application") + .description("This is a sample application for difference between @Operation & @ApiResponse") + .version("1.0.0")); } } diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/controller/CustomerController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/controller/CustomerController.java index 0811af56ec..436b848904 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/controller/CustomerController.java +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerresponses/controller/CustomerController.java @@ -4,10 +4,12 @@ import com.baeldung.swaggerresponses.response.CustomerResponse; import com.baeldung.swaggerresponses.response.ErrorResponse; import com.baeldung.swaggerresponses.service.CustomerService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -15,7 +17,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Api("Customer Controller") +@Tag(name = "Customer Controller") @RestController @RequestMapping("/customers") public class CustomerController { @@ -26,11 +28,11 @@ public class CustomerController { this.customerService = customerService; } - @ApiOperation(value = "Gets customer by ID", response = CustomerResponse.class, notes = "Customer must exist") + @Operation(summary = "Gets customer by ID", description = "Customer must exist") @ApiResponses(value = { - @ApiResponse(code = 400, message = "Invalid ID supplied"), - @ApiResponse(code = 404, message = "Customer not found"), - @ApiResponse(code = 500, message = "Internal server error", response = ErrorResponse.class) }) + @ApiResponse(responseCode = "200", description = "Ok", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = CustomerResponse.class)) }), + @ApiResponse(responseCode = "400", description = "Invalid ID supplied"), @ApiResponse(responseCode = "404", description = "Customer not found"), + @ApiResponse(responseCode = "500", description = "Internal server error", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class)) }) }) @GetMapping("/{id}") public ResponseEntity getCustomer(@PathVariable("id") Long id) { return ResponseEntity.ok(customerService.getById(id)); diff --git a/spring-boot-modules/spring-boot-testing-spock/README.md b/spring-boot-modules/spring-boot-testing-spock/README.md new file mode 100644 index 0000000000..ab8193ab4e --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/README.md @@ -0,0 +1,7 @@ +## Spring Boot Testing + +This module contains articles about Spring Boot testing with Spock framework + +### Relevant Articles: + +- [Testing with Spring and Spock](https://www.baeldung.com/spring-spock-testing) diff --git a/spring-boot-modules/spring-boot-testing-spock/pom.xml b/spring-boot-modules/spring-boot-testing-spock/pom.xml new file mode 100644 index 0000000000..c82d88ccfb --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + spring-boot-testing-spock + spring-boot-testing-spock + war + This is simple boot application for demonstrating spock framework testing features. + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + + + + + + org.apache.logging.log4j + log4j-bom + ${log4j2.version} + import + pom + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.spockframework + spock-core + ${spock.version} + test + + + org.spockframework + spock-spring + ${spock.version} + test + + + + + spring-boot-testing-spock + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-war-plugin + + + org.codehaus.gmavenplus + gmavenplus-plugin + ${gmavenplus-plugin.version} + + + + compileTests + + + + + 17 + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + + + + + com.baeldung.boot.Application + 2.4-M1-groovy-4.0 + 3.0.0 + 3.10.1 + 2.17.1 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-spock/src/main/java/com/baeldung/boot/Application.java b/spring-boot-modules/spring-boot-testing-spock/src/main/java/com/baeldung/boot/Application.java new file mode 100644 index 0000000000..cb0d0c1532 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/src/main/java/com/baeldung/boot/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.boot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +@SpringBootApplication +public class Application { + private static ApplicationContext applicationContext; + + public static void main(String[] args) { + applicationContext = SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/controller/rest/WebController.java b/spring-boot-modules/spring-boot-testing-spock/src/main/java/com/baeldung/boot/controller/rest/WebController.java similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/main/java/com/baeldung/boot/controller/rest/WebController.java rename to spring-boot-modules/spring-boot-testing-spock/src/main/java/com/baeldung/boot/controller/rest/WebController.java diff --git a/spring-boot-modules/spring-boot-testing-spock/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing-spock/src/main/resources/application.properties new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/src/main/resources/application.properties @@ -0,0 +1,2 @@ + + diff --git a/spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/LoadContextTest.groovy b/spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/LoadContextTest.groovy similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/LoadContextTest.groovy rename to spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/LoadContextTest.groovy diff --git a/spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy b/spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy rename to spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy diff --git a/spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy alias b/spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy alias similarity index 100% rename from spring-boot-modules/spring-boot-testing/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy alias rename to spring-boot-modules/spring-boot-testing-spock/src/test/groovy/com/baeldung/boot/WebControllerTest.groovy alias diff --git a/spring-boot-modules/spring-boot-testing-spock/src/test/java/com/baeldung/boot/SpringContextTest.java b/spring-boot-modules/spring-boot-testing-spock/src/test/java/com/baeldung/boot/SpringContextTest.java new file mode 100644 index 0000000000..f3c8b9a954 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/src/test/java/com/baeldung/boot/SpringContextTest.java @@ -0,0 +1,15 @@ +package com.baeldung.boot; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-modules/spring-boot-testing-spock/src/test/resources/application-test.properties b/spring-boot-modules/spring-boot-testing-spock/src/test/resources/application-test.properties new file mode 100644 index 0000000000..a2c9b6d480 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/src/test/resources/application-test.properties @@ -0,0 +1,2 @@ +# test properties +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-spock/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-testing-spock/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..9553dcad41 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-spock/src/test/resources/logback-test.xml @@ -0,0 +1,12 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/spring-boot-modules/spring-boot-testing/README.md b/spring-boot-modules/spring-boot-testing/README.md index 19f5ca0f59..407cc410e7 100644 --- a/spring-boot-modules/spring-boot-testing/README.md +++ b/spring-boot-modules/spring-boot-testing/README.md @@ -8,7 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Testing with Spring and Spock](https://www.baeldung.com/spring-spock-testing) - [Exclude Auto-Configuration Classes in Spring Boot Tests](https://www.baeldung.com/spring-boot-exclude-auto-configuration-test) - [Embedded Redis Server with Spring Boot Test](https://www.baeldung.com/spring-embedded-redis) - [Testing Spring Boot @ConfigurationProperties](https://www.baeldung.com/spring-boot-testing-configurationproperties) diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index ace6307761..2098ac767d 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -67,19 +67,6 @@ ${redis.version} test - - - org.spockframework - spock-core - ${spock.version} - test - - - org.spockframework - spock-spring - ${spock.version} - test - @@ -120,21 +107,6 @@ ${project.build.outputDirectory}/git.properties - - org.codehaus.gmavenplus - gmavenplus-plugin - ${gmavenplus-plugin.version} - - - - compileTests - - - - - 17 - - org.apache.maven.plugins maven-compiler-plugin @@ -148,7 +120,7 @@ com.baeldung.boot.Application 2.2.4 2.4-M1-groovy-4.0 - 2.1.0 + 3.0.0 3.10.1 0.7.2 2.5.0 diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation.properties b/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation.properties new file mode 100644 index 0000000000..6b4c881dc0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing/src/test/resources/property-validation.properties @@ -0,0 +1,4 @@ +validate.propertiesMap.first=prop1 +validate.propertiesMap.second=prop2 + +validate.mail_config.address=user1@test \ No newline at end of file diff --git a/spring-cloud-modules/pom.xml b/spring-cloud-modules/pom.xml index dafc5b628e..c4b89d6db0 100644 --- a/spring-cloud-modules/pom.xml +++ b/spring-cloud-modules/pom.xml @@ -32,7 +32,7 @@ spring-cloud-aws spring-cloud-consul spring-cloud-zuul-eureka-integration - spring-cloud-contract + spring-cloud-kubernetes spring-cloud-open-service-broker spring-cloud-archaius @@ -43,7 +43,7 @@ spring-cloud-zuul spring-cloud-zuul-fallback spring-cloud-ribbon-retry - spring-cloud-circuit-breaker + spring-cloud-eureka-self-preservation spring-cloud-openfeign spring-cloud-netflix-feign @@ -52,7 +52,7 @@ spring-cloud-dapr spring-cloud-docker spring-cloud-bus - spring-cloud-data-flow + spring-cloud-sleuth spring-cloud-open-telemetry spring-cloud-azure diff --git a/spring-cloud-modules/spring-cloud-azure/pom.xml b/spring-cloud-modules/spring-cloud-azure/pom.xml index 5153eecc9f..5271ee7e7e 100644 --- a/spring-cloud-modules/spring-cloud-azure/pom.xml +++ b/spring-cloud-modules/spring-cloud-azure/pom.xml @@ -42,7 +42,6 @@ - com.azure.spring diff --git a/spring-cloud-modules/spring-cloud-circuit-breaker/pom.xml b/spring-cloud-modules/spring-cloud-circuit-breaker/pom.xml index 3fe060c0b6..e2ba6433c0 100644 --- a/spring-cloud-modules/spring-cloud-circuit-breaker/pom.xml +++ b/spring-cloud-modules/spring-cloud-circuit-breaker/pom.xml @@ -18,7 +18,7 @@ org.springframework.boot spring-boot-dependencies - 2.2.4.RELEASE + ${spring-boot-dependencies.version} pom import @@ -38,7 +38,8 @@ - 1.0.2.RELEASE + 3.0.1 + 3.0.2 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-contract/pom.xml b/spring-cloud-modules/spring-cloud-contract/pom.xml index bfbac19a81..7a9c8c32cd 100644 --- a/spring-cloud-modules/spring-cloud-contract/pom.xml +++ b/spring-cloud-modules/spring-cloud-contract/pom.xml @@ -60,7 +60,7 @@ - 2.1.1.RELEASE + 4.0.3 2.1.4.RELEASE 2.17.1 diff --git a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml index b561000a83..680e2e1795 100644 --- a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml +++ b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml @@ -40,6 +40,16 @@ ${project.parent.version} test + + io.rest-assured + rest-assured + + + org.codehaus.groovy + groovy-xml + + + \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-producer/pom.xml b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-producer/pom.xml index b80b86580f..35dd9596f7 100644 --- a/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-producer/pom.xml +++ b/spring-cloud-modules/spring-cloud-contract/spring-cloud-contract-producer/pom.xml @@ -29,6 +29,16 @@ org.springframework.boot spring-boot-starter-data-rest + + io.rest-assured + rest-assured + + + org.codehaus.groovy + groovy-xml + + + @@ -36,7 +46,7 @@ org.springframework.cloud spring-cloud-contract-maven-plugin - ${spring-cloud.version} + 2.1.1.RELEASE true com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass @@ -46,8 +56,4 @@ - - 2.1.1.RELEASE - - \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml b/spring-cloud-modules/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml index 9b33411aaa..072d4a2de0 100644 --- a/spring-cloud-modules/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml +++ b/spring-cloud-modules/spring-cloud-data-flow/spring-cloud-data-flow-stream-processing/data-flow-server/pom.xml @@ -17,13 +17,6 @@ - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - org.springframework.cloud spring-cloud-dataflow-dependencies @@ -31,13 +24,6 @@ pom import - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud-dependencies.version} - pom - import - @@ -45,6 +31,7 @@ org.springframework.cloud spring-cloud-starter-dataflow-server-local + 1.7.4.RELEASE org.hibernate @@ -62,13 +49,22 @@ ${byte-buddy.version} test + + org.codehaus.groovy + groovy + ${groovy.version} + + + org.springframework.session + spring-session-data-redis + - 1.3.1.RELEASE - Edgware.SR6 - 5.2.12.Final - 1.5.22.RELEASE + 2.0.0.RELEASE + 5.6.0.Final + 2.1.4.RELEASE + 3.0.8 \ No newline at end of file diff --git a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml index ecf275fac6..6f11451bfb 100644 --- a/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml +++ b/spring-cloud-modules/spring-cloud-open-telemetry/spring-cloud-open-telemetry2/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 spring-cloud-open-telemetry2 diff --git a/spring-reactive-modules/spring-reactive-exceptions/pom.xml b/spring-reactive-modules/spring-reactive-exceptions/pom.xml index 0dca81c529..a9fdb675f5 100644 --- a/spring-reactive-modules/spring-reactive-exceptions/pom.xml +++ b/spring-reactive-modules/spring-reactive-exceptions/pom.xml @@ -20,10 +20,6 @@ org.springframework.boot spring-boot-starter-webflux - - org.springframework.boot - spring-boot-starter-web - org.projectlombok lombok diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 2c9a8e3dfe..4fde64bc7a 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -20,7 +20,7 @@ spring-security-cognito spring-security-core spring-security-core-2 - + spring-security-legacy-oidc spring-security-oauth2 spring-security-oauth2-sso diff --git a/spring-security-modules/spring-security-oauth2-testing/reactive-resource-server/pom.xml b/spring-security-modules/spring-security-oauth2-testing/reactive-resource-server/pom.xml index 86f73cfdbf..3d5ff0cb69 100644 --- a/spring-security-modules/spring-security-oauth2-testing/reactive-resource-server/pom.xml +++ b/spring-security-modules/spring-security-oauth2-testing/reactive-resource-server/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 diff --git a/spring-security-modules/spring-security-oauth2-testing/servlet-resource-server/pom.xml b/spring-security-modules/spring-security-oauth2-testing/servlet-resource-server/pom.xml index 271cc7dc18..eb507fc3d3 100644 --- a/spring-security-modules/spring-security-oauth2-testing/servlet-resource-server/pom.xml +++ b/spring-security-modules/spring-security-oauth2-testing/servlet-resource-server/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 diff --git a/spring-security-modules/spring-security-saml2/pom.xml b/spring-security-modules/spring-security-saml2/pom.xml index 0e92339bc0..6de69fd201 100644 --- a/spring-security-modules/spring-security-saml2/pom.xml +++ b/spring-security-modules/spring-security-saml2/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 diff --git a/spring-security-modules/spring-security-web-react/pom.xml b/spring-security-modules/spring-security-web-react/pom.xml index 93119cbe66..3a519acf09 100644 --- a/spring-security-modules/spring-security-web-react/pom.xml +++ b/spring-security-modules/spring-security-web-react/pom.xml @@ -129,7 +129,6 @@ - diff --git a/spring-security-modules/spring-security-web-rest/README.md b/spring-security-modules/spring-security-web-rest/README.md index 5a94504762..a11bc7e8d6 100644 --- a/spring-security-modules/spring-security-web-rest/README.md +++ b/spring-security-modules/spring-security-web-rest/README.md @@ -9,7 +9,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [Setting Up Swagger 2 with a Spring REST API Using Springfox](https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api) - [Custom Error Message Handling for REST API](https://www.baeldung.com/global-error-handler-in-a-spring-rest-api) - [Spring Security Context Propagation with @Async](https://www.baeldung.com/spring-security-async-principal-propagation) - [Servlet 3 Async Support with Spring MVC and Spring Security](https://www.baeldung.com/spring-mvc-async-security) diff --git a/spring-security-modules/spring-security-web-rest/pom.xml b/spring-security-modules/spring-security-web-rest/pom.xml index 99a040293b..76d9ad37de 100644 --- a/spring-security-modules/spring-security-web-rest/pom.xml +++ b/spring-security-modules/spring-security-web-rest/pom.xml @@ -139,17 +139,6 @@ - - - io.springfox - springfox-swagger2 - ${springfox-swagger.version} - - - io.springfox - springfox-swagger-ui - ${springfox-swagger.version} - commons-fileupload commons-fileupload @@ -246,8 +235,6 @@ 1.1.0.Final 2.9.0 - - 3.0.0 1.6.1 diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml index 9cd6f71892..c529951b07 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/pom.xml @@ -41,21 +41,16 @@ openapi-generator 3.3.4 - - io.springfox - springfox-oas - ${springfox-version} - - - io.springfox - springfox-swagger-ui - ${springfox-version} - com.fasterxml.jackson.core jackson-databind 2.10.0.pr3 + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + @@ -101,6 +96,7 @@ 11 3.0.0 2.17.1 + 1.7.0 \ No newline at end of file diff --git a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache index 34f4afac3a..ed806c6282 100644 --- a/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache +++ b/spring-swagger-codegen/custom-validations-opeanpi-codegen/src/main/resources/openapi/templates/api.mustache @@ -37,7 +37,6 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.http.codec.multipart.Part; {{/reactive}} -import springfox.documentation.annotations.ApiIgnore; {{#useBeanValidation}} import javax.validation.Valid; @@ -129,13 +128,13 @@ public interface {{classname}} { produces = { {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} }{{/hasProduces}}{{#hasConsumes}}, consumes = { {{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}} }{{/hasConsumes}}{{/singleContentTypes}} ) - {{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},{{/-last}}{{#-last}}{{#reactive}}, {{/reactive}}{{/-last}}{{/allParams}}{{#reactive}}@ApiIgnore final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, @ApiIgnore final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} { + {{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{^-last}},{{/-last}}{{#-last}}{{#reactive}}, {{/reactive}}{{/-last}}{{/allParams}}{{#reactive}}final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} { {{#delegate-method}} return {{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, pageable{{/vendorExtensions.x-spring-paginated}}); } // Override this method - {{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}@ApiIgnore final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, @ApiIgnore final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} { + {{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{#responseWrapper}}{{.}}<{{/responseWrapper}}ResponseEntity<{{>returnTypes}}>{{#responseWrapper}}>{{/responseWrapper}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#reactive}}Flux{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}} final ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}, final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}} { {{/delegate-method}} {{^isDelegate}} {{>methodBody}} diff --git a/spring-swagger-codegen/pom.xml b/spring-swagger-codegen/pom.xml index 93cb51d07c..d4fff7eb63 100644 --- a/spring-swagger-codegen/pom.xml +++ b/spring-swagger-codegen/pom.xml @@ -10,8 +10,9 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml index c9ba912feb..b2e97c7a49 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml @@ -79,6 +79,11 @@ joda-time ${jodatime-version} + + javax.annotation + javax.annotation-api + 1.3.2 + diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml index 493b7201ee..d3f57474ef 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml @@ -22,12 +22,10 @@ org.springframework.boot spring-boot-starter-web - ${spring.version} org.springframework.boot spring-boot-starter-test - ${spring.version} test @@ -37,14 +35,12 @@ org.springframework.boot spring-boot-maven-plugin - ${spring.version} 0.0.1-SNAPSHOT - 1.5.10.RELEASE \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics/pom.xml b/spring-web-modules/spring-mvc-basics/pom.xml index 0f1d423ca2..94f3ac1e9e 100644 --- a/spring-web-modules/spring-mvc-basics/pom.xml +++ b/spring-web-modules/spring-mvc-basics/pom.xml @@ -61,7 +61,7 @@ - 2.3.5 + 2.3.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-3/README.md b/spring-web-modules/spring-mvc-java-3/README.md index 7d843af9ea..f61e004bb5 100644 --- a/spring-web-modules/spring-mvc-java-3/README.md +++ b/spring-web-modules/spring-mvc-java-3/README.md @@ -1 +1,2 @@ ### Relevant Articles: +- [Java IllegalStateException: “getInputStream() has already been called for this request”](https://www.baeldung.com/java-servletrequest-illegalstateexception) diff --git a/spring-web-modules/spring-mvc-java-3/pom.xml b/spring-web-modules/spring-mvc-java-3/pom.xml index 3a49a5f9af..4d669c7e7b 100644 --- a/spring-web-modules/spring-mvc-java-3/pom.xml +++ b/spring-web-modules/spring-mvc-java-3/pom.xml @@ -1,7 +1,7 @@ + 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"> 4.0.0 spring-mvc-java-3 diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index d83a83c690..88294c7811 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -37,16 +37,16 @@ resilience4j-timelimiter ${resilience4j.version} - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - com.google.guava - guava - ${guava.version} - + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + com.google.guava + guava + ${guava.version} + diff --git a/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/resttemplate/RestTemplateApplication.java b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/resttemplate/RestTemplateApplication.java new file mode 100644 index 0000000000..ca1e141d44 --- /dev/null +++ b/spring-web-modules/spring-resttemplate-2/src/main/java/com/baeldung/resttemplate/RestTemplateApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.resttemplate; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class RestTemplateApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(RestTemplateApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.servlet.encoding.charset", "ISO-8859-1")); + app.run(args); + } +} diff --git a/spring-web-modules/spring-resttemplate-2/src/test/java/com/baeldung/resttemplate/postjson/RestTemplatePostRequestEncodingLiveTest.java b/spring-web-modules/spring-resttemplate-2/src/test/java/com/baeldung/resttemplate/postjson/RestTemplatePostRequestEncodingLiveTest.java new file mode 100644 index 0000000000..803ab96ba4 --- /dev/null +++ b/spring-web-modules/spring-resttemplate-2/src/test/java/com/baeldung/resttemplate/postjson/RestTemplatePostRequestEncodingLiveTest.java @@ -0,0 +1,59 @@ +package com.baeldung.resttemplate.postjson; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +import org.json.JSONException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import com.baeldung.resttemplate.RestTemplateApplication; +import com.baeldung.resttemplate.web.dto.Person; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = RestTemplateApplication.class) +public class RestTemplatePostRequestEncodingLiveTest { + private static String createPersonUrl; + private static RestTemplate restTemplate; + + @BeforeClass + public static void runBeforeAllTestMethods() throws JSONException { + createPersonUrl = "http://localhost:8080/spring-rest/createPerson"; + restTemplate = new RestTemplate(); + } + + @Test + public void givenJapaneseNameInDataWithoutHeaderEncoding_whenDataIsPostedByPostForObject_thenSaveIncorrectly() { + Person japanese = new Person(100, "関連当"); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity request = new HttpEntity<>(japanese, headers); + + Person person = restTemplate.postForObject(createPersonUrl, request, Person.class); + assertNotNull(person); + assertNotEquals("関連当", person.getName()); + } + + @Test + public void givenJapaneseNameInDataWithHeaderEncoding_whenDataIsPostedByPostForObject_thenSaveCorrectly() { + Person japanese = new Person(100, "関連当"); + + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-type", "application/json;charset=UTF-8"); + HttpEntity request = new HttpEntity<>(japanese, headers); + + Person person = restTemplate.postForObject(createPersonUrl, request, Person.class); + assertNotNull(person); + assertEquals("関連当", person.getName()); + } +} \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml index 8d1b43f2c6..8c26e9947d 100644 --- a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml @@ -1,95 +1,95 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> - 4.0.0 + 4.0.0 - com.baeldung.spring-thymeleaf-attributes.module - accessing-session-attributes - 0.0.1-SNAPSHOT - war - - - com.baeldung.spring-thymeleaf-attributes - spring-thymeleaf-attributes-modules + com.baeldung.spring-thymeleaf-attributes.module + accessing-session-attributes 0.0.1-SNAPSHOT - ../pom.xml - + war - - - jakarta.servlet - jakarta.servlet-api - provided - - - org.springframework.boot - spring-boot-starter-web - - - org.thymeleaf - thymeleaf-spring6 - ${thymeleaf.spring6.version} - - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.engine.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.engine.version} - test - + + com.baeldung.spring-thymeleaf-attributes + spring-thymeleaf-attributes + 0.0.1-SNAPSHOT + ../pom.xml + - + + + jakarta.servlet + jakarta.servlet-api + provided + + + org.springframework.boot + spring-boot-starter-web + + + org.thymeleaf + thymeleaf-spring6 + ${thymeleaf.spring6.version} + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.engine.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.engine.version} + test + - - - - src/main/resources - - + - - - org.springframework.boot - spring-boot-maven-plugin - - - -Dfile.encoding="UTF-8" -Xdebug - -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 - - - - - + + + + src/main/resources + + - - com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer - UTF-8 - UTF-8 - UTF-8 - true - true - 5.9.3 - 5.3.1 - 3.1.1.RELEASE - + + + org.springframework.boot + spring-boot-maven-plugin + + + -Dfile.encoding="UTF-8" -Xdebug + -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 + + + + + + + + com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer + UTF-8 + UTF-8 + UTF-8 + true + true + 5.9.3 + 5.3.1 + 3.1.1.RELEASE + \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/pom.xml index 44806cc29f..c7b1b7669d 100644 --- a/spring-web-modules/spring-thymeleaf-attributes/pom.xml +++ b/spring-web-modules/spring-thymeleaf-attributes/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.baeldung.spring-thymeleaf-attributes - spring-thymeleaf-attributes-modules + spring-thymeleaf-attributes 0.0.1-SNAPSHOT pom diff --git a/spring-web-modules/spring-thymeleaf/README.md b/spring-web-modules/spring-thymeleaf/README.md index 653e6df5b9..2d1bc848d8 100644 --- a/spring-web-modules/spring-thymeleaf/README.md +++ b/spring-web-modules/spring-thymeleaf/README.md @@ -10,6 +10,7 @@ This module contains articles about Spring with Thymeleaf - [How to Work with Dates in Thymeleaf](https://www.baeldung.com/dates-in-thymeleaf) - [Working with Fragments in Thymeleaf](https://www.baeldung.com/spring-thymeleaf-fragments) - [JavaScript Function Call with Thymeleaf](https://www.baeldung.com/thymeleaf-js-function-call) +- [Add a Checked Attribute to Input Conditionally in Thymeleaf](https://www.baeldung.com/thymeleaf-conditional-checked-attribute) - [[next -->]](/spring-thymeleaf-2) ### Build the Project diff --git a/testing-modules/mockito-2/README.md b/testing-modules/mockito-2/README.md index 3bb2b1543e..ac931a108f 100644 --- a/testing-modules/mockito-2/README.md +++ b/testing-modules/mockito-2/README.md @@ -4,3 +4,5 @@ This module contains articles about Mockito ### Relevant Articles: - [Mocking a Singleton With Mockito](https://www.baeldung.com/java-mockito-singleton) +- [Resolving Mockito Exception: Wanted But Not Invoked](https://www.baeldung.com/mockito-exception-wanted-but-not-invoked) +- [Matching Null With Mockito](https://www.baeldung.com/mockito-match-null) diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index 25e9fd51a2..0e0f19b6b3 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 mockito-2 diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java new file mode 100644 index 0000000000..d15196faa5 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Helper.java @@ -0,0 +1,9 @@ +package com.baeldung.nullmatcher; + +class Helper { + + String concat(String a, String b) { + return a + b; + } + +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java new file mode 100644 index 0000000000..e3c73f9d8a --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/nullmatcher/Main.java @@ -0,0 +1,11 @@ +package com.baeldung.nullmatcher; + +class Main { + + Helper helper = new Helper(); + + String methodUnderTest() { + return helper.concat("Baeldung", null); + } + +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java new file mode 100644 index 0000000000..dd8e04065b --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Helper.java @@ -0,0 +1,9 @@ +package com.baeldung.wantedbutnotinvocked; + +class Helper { + + String getBaeldungString() { + return "Baeldung"; + } + +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java new file mode 100644 index 0000000000..31134000d2 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/wantedbutnotinvocked/Main.java @@ -0,0 +1,14 @@ +package com.baeldung.wantedbutnotinvocked; + +class Main { + + Helper helper = new Helper(); + + String methodUnderTest(int i) { + if (i > 5) { + return helper.getBaeldungString(); + } + return "Hello"; + } + +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java new file mode 100644 index 0000000000..a0245977e0 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/nullmatcher/MainUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.nullmatcher; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.isNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +class MainUnitTest { + + @Mock + Helper helper; + + @InjectMocks + Main main; + + @BeforeEach + void openMocks() { + MockitoAnnotations.openMocks(this); + } + + @Test + void whenMethodUnderTest_thenSecondParameterNull() { + main.methodUnderTest(); + Mockito.verify(helper) + .concat("Baeldung", null); + } + + @Test + void whenMethodUnderTest_thenSecondParameterNullWithMatchers() { + main.methodUnderTest(); + Mockito.verify(helper) + .concat(any(), isNull()); + } + +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java new file mode 100644 index 0000000000..6927b13a06 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/wantedbutnotinvocked/MainUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.wantedbutnotinvocked; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +class MainUnitTest { + + @Mock + Helper helper; + + @InjectMocks + Main main = new Main(); + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void givenValueUpperThan5_WhenMethodUnderTest_ThenDelegatesToHelperClass() { + main.methodUnderTest(7); + Mockito.verify(helper) + .getBaeldungString(); + } + + // Uncomment the next line to see the error + // @Test + void givenValueLowerThan5_WhenMethodUnderTest_ThenDelegatesToGetBaeldungString() { + main.methodUnderTest(3); + Mockito.verify(helper) + .getBaeldungString(); + } + +} diff --git a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java index 6041ee1a9b..705f2ac7ad 100644 --- a/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java +++ b/testing-modules/mockito-simple/src/test/java/com/baeldung/mockito/mockfinal/MockFinalsUnitTest.java @@ -3,10 +3,8 @@ package com.baeldung.mockito.mockfinal; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; import org.junit.jupiter.api.Test; -import org.mockito.MockMakers; import com.baeldung.mockito.FinalList; import com.baeldung.mockito.MyList; @@ -30,14 +28,4 @@ class MockFinalsUnitTest { assertThat(mock.size()).isNotEqualTo(1); } - - @Test - public void whenMockFinalMethodMockWorks_withInlineMockMaker() { - MyList myList = new MyList(); - - MyList mock = mock(MyList.class, withSettings().mockMaker(MockMakers.INLINE)); - when(mock.finalMethod()).thenReturn(1); - - assertThat(mock.finalMethod()).isNotEqualTo(myList.finalMethod()); - } } diff --git a/testing-modules/mockito-simple/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/testing-modules/mockito-simple/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index ca6ee9cea8..0000000000 --- a/testing-modules/mockito-simple/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1 +0,0 @@ -mock-maker-inline \ No newline at end of file diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index 281fff38c2..88fc6367aa 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -67,7 +67,7 @@ 0.15 1.5 3.5.1 - 1.41 + 1.49 1.1 diff --git a/testing-modules/mocks/src/main/java/com/baeldung/jmockit/AdvancedCollaborator.java b/testing-modules/mocks/src/main/java/com/baeldung/jmockit/AdvancedCollaborator.java index ef7484cfdd..61afccc745 100644 --- a/testing-modules/mocks/src/main/java/com/baeldung/jmockit/AdvancedCollaborator.java +++ b/testing-modules/mocks/src/main/java/com/baeldung/jmockit/AdvancedCollaborator.java @@ -8,12 +8,12 @@ public class AdvancedCollaborator { i = string.length(); } public String methodThatCallsPrivateMethod(int i){ - return privateMethod() + i; + return protectedMethod() + i; } public int methodThatReturnsThePrivateField(){ return privateField; } - private String privateMethod(){ + protected String protectedMethod(){ return "default:"; } class InnerAdvancedCollaborator{} diff --git a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/AdvancedCollaboratorIntegrationTest.java b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/AdvancedCollaboratorIntegrationTest.java index e55a69895f..ff69a701e7 100644 --- a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/AdvancedCollaboratorIntegrationTest.java +++ b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/AdvancedCollaboratorIntegrationTest.java @@ -1,37 +1,33 @@ package com.baeldung.jmockit; -import static org.junit.Assert.assertEquals; +import mockit.*; +import org.junit.Test; -import java.util.ArrayList; +import java.io.Serializable; +import java.util.Comparator; import java.util.List; -import com.baeldung.jmockit.AdvancedCollaborator; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; -import mockit.Deencapsulation; -import mockit.Expectations; -import mockit.Invocation; -import mockit.Mock; -import mockit.MockUp; -import mockit.Mocked; -import mockit.Tested; -import mockit.integration.junit4.JMockit; +public class AdvancedCollaboratorIntegrationTest { -@RunWith(JMockit.class) -public class AdvancedCollaboratorIntegrationTest & Comparable>> { + interface IList extends List {} + interface IComparator extends Comparator, Serializable {} + static class MultiMock { + IList get() { return null; } + IComparator compareTo() { return null; } + } @Tested private AdvancedCollaborator mock; - @Mocked - private MultiMock multiMock; @Test public void testToMockUpPrivateMethod() { new MockUp() { @Mock - private String privateMethod() { + protected String protectedMethod() { return "mocked: "; } }; @@ -52,40 +48,26 @@ public class AdvancedCollaboratorIntegrationTest } @Test - public void testToSetPrivateFieldDirectly() { - Deencapsulation.setField(mock, "privateField", 10); - assertEquals(10, mock.methodThatReturnsThePrivateField()); + public void testToSetPrivateFieldDirectly(@Injectable("10") int privateField) { + assertEquals(10, privateField); } @Test public void testToGetPrivateFieldDirectly() { - int value = Deencapsulation.getField(mock, "privateField"); - assertEquals(5, value); + assertEquals(5, mock.methodThatReturnsThePrivateField()); } @Test @SuppressWarnings("unchecked") - public void testMultipleInterfacesWholeTest() { + public void testMultipleInterfacesWholeTest(@Mocked MultiMock multiMock) { new Expectations() { { - multiMock.get(5); result = "foo"; - multiMock.compareTo((List) any); result = 0; + multiMock.get(); result = null; + multiMock.compareTo(); result = null; } }; - assertEquals("foo", multiMock.get(5)); - assertEquals(0, multiMock.compareTo(new ArrayList<>())); + assertNull(multiMock.get()); + assertNull(multiMock.compareTo()); } - @Test - @SuppressWarnings("unchecked") - public & Comparable>> void testMultipleInterfacesOneMethod(@Mocked M mock) { - new Expectations() { - { - mock.get(5); result = "foo"; - mock.compareTo((List) any); - result = 0; } - }; - assertEquals("foo", mock.get(5)); - assertEquals(0, mock.compareTo(new ArrayList<>())); - } } diff --git a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ExpectationsIntegrationTest.java b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ExpectationsIntegrationTest.java index 1ff90111d1..b17f7b183f 100644 --- a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ExpectationsIntegrationTest.java +++ b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ExpectationsIntegrationTest.java @@ -1,23 +1,17 @@ package com.baeldung.jmockit; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.List; - -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.Test; -import org.junit.runner.RunWith; - import mockit.Delegate; import mockit.Expectations; import mockit.Mocked; import mockit.Verifications; -import mockit.integration.junit4.JMockit; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; -@RunWith(JMockit.class) @SuppressWarnings("unchecked") public class ExpectationsIntegrationTest { @@ -91,15 +85,11 @@ public class ExpectationsIntegrationTest { @Test public void testCustomArgumentMatching(@Mocked ExpectationsCollaborator mock) { new Expectations() {{ - mock.methodForArgThat(withArgThat(new BaseMatcher() { - @Override + mock.methodForArgThat(with(new Delegate() { public boolean matches(Object item) { return item instanceof Model && "info".equals(((Model) item).getInfo()); } - @Override - public void describeTo(Description description) { - } })); }}; mock.methodForArgThat(new Model()); diff --git a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/LoginControllerIntegrationTest.java b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/LoginControllerIntegrationTest.java index df3eeccca2..c2b8bea1ea 100644 --- a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/LoginControllerIntegrationTest.java +++ b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/LoginControllerIntegrationTest.java @@ -1,18 +1,13 @@ package com.baeldung.jmockit; -import mockit.*; -import mockit.integration.junit4.JMockit; import com.baeldung.testCase.LoginController; import com.baeldung.testCase.LoginDao; import com.baeldung.testCase.LoginService; import com.baeldung.testCase.UserForm; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; +import mockit.*; import org.junit.Assert; import org.junit.Test; -import org.junit.runner.RunWith; -@RunWith(JMockit.class) public class LoginControllerIntegrationTest { @Injectable @@ -110,16 +105,10 @@ public class LoginControllerIntegrationTest { loginService.login((UserForm) any); result = true; // complex matcher - loginService.setCurrentUser(withArgThat(new BaseMatcher() { - @Override + loginService.setCurrentUser(with(new Delegate() { public boolean matches(Object item) { return item instanceof String && ((String) item).startsWith("foo"); } - - @Override - public void describeTo(Description description) { - //NOOP - } })); }}; diff --git a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/PerformerIntegrationTest.java b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/PerformerIntegrationTest.java index fb94ae908b..d2a5c52154 100644 --- a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/PerformerIntegrationTest.java +++ b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/PerformerIntegrationTest.java @@ -1,15 +1,8 @@ package com.baeldung.jmockit; -import com.baeldung.jmockit.Collaborator; -import com.baeldung.jmockit.Model; -import com.baeldung.jmockit.Performer; -import org.junit.Test; -import org.junit.runner.RunWith; - import mockit.*; -import mockit.integration.junit4.JMockit; +import org.junit.Test; -@RunWith(JMockit.class) public class PerformerIntegrationTest { @Injectable diff --git a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ReusingIntegrationTest.java b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ReusingIntegrationTest.java index 30b17ee2e4..f702f776fc 100644 --- a/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ReusingIntegrationTest.java +++ b/testing-modules/mocks/src/test/java/com/baeldung/jmockit/ReusingIntegrationTest.java @@ -1,20 +1,9 @@ package com.baeldung.jmockit; -import com.baeldung.jmockit.Collaborator; -import com.baeldung.jmockit.Model; -import com.baeldung.jmockit.Performer; +import mockit.*; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; -import mockit.Verifications; -import mockit.integration.junit4.JMockit; - -@RunWith(JMockit.class) public class ReusingIntegrationTest { @Injectable diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index 323c46a5fc..f8005092ae 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -26,23 +26,6 @@ commons-lang3 ${commons-lang3.version} - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpcore - ${httpcore.version} - com.fasterxml.jackson.core @@ -66,6 +49,7 @@ io.cucumber cucumber-junit ${cucumber.version} + test org.jbehave @@ -73,11 +57,6 @@ ${jbehave.version} test - - com.intuit.karate - karate-apache - ${karate.version} - com.intuit.karate karate-junit4 @@ -94,6 +73,18 @@ true + + + + src/test/java + + **/*.java + + + + src/test/resources + + org.apache.maven.plugins @@ -145,9 +136,7 @@ 2.9.0 6.8.0 2.21.0 - 0.6.1 - 4.4.5 - 4.5.2 + 1.3.1 4.1 diff --git a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateIntegrationTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateIntegrationTest.java index 59d14e6ae0..91dbd7599e 100644 --- a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateIntegrationTest.java +++ b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateIntegrationTest.java @@ -2,17 +2,16 @@ package com.baeldung.rest.karate; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import cucumber.api.CucumberOptions; +import com.intuit.karate.junit4.Karate; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.runner.RunWith; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -//We need to upgrade to latest version of Karate for JDK17 --- JAVA-22250 -//@RunWith(Karate.class) -@CucumberOptions(features = "classpath:karate") +@RunWith(Karate.class) public class KarateIntegrationTest { private static final int PORT_NUMBER = 8097; @@ -20,7 +19,7 @@ public class KarateIntegrationTest { private static final WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options().port(PORT_NUMBER)); @BeforeClass - public static void setUp() throws Exception { + public static void setUp() { wireMockServer.start(); configureFor("localhost", PORT_NUMBER); @@ -30,7 +29,7 @@ public class KarateIntegrationTest { .withHeader("Content-Type", "application/json") .withBody("{ \"id\": \"1234\", name: \"John Smith\" }"))); stubFor(post(urlEqualTo("/user/create")) - .withHeader("content-type", equalTo("application/json")) + .withHeader("content-type", equalTo("application/json; charset=UTF-8")) .withRequestBody(containing("id")) .willReturn(aResponse() .withStatus(200) @@ -40,7 +39,7 @@ public class KarateIntegrationTest { } @AfterClass - public static void tearDown() throws Exception { + public static void tearDown() { wireMockServer.stop(); } diff --git a/testing-modules/rest-testing/src/test/resources/karate/user.feature b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/user.feature similarity index 100% rename from testing-modules/rest-testing/src/test/resources/karate/user.feature rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/user.feature diff --git a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java index d901bf3c34..50861d2e57 100644 --- a/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java +++ b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java @@ -10,7 +10,7 @@ public class BaeldungHomePage { private SeleniumConfig config; @FindBy(css = ".nav--logo_mobile") private WebElement title; - @FindBy(css = ".menu-start-here > a") + @FindBy(css = ".header--menu") private WebElement startHere; public BaeldungHomePage(SeleniumConfig config) { diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java index c6abda08ee..e585aa90f3 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/clickusingjavascript/SeleniumJavaScriptClickLiveTest.java @@ -39,22 +39,21 @@ public class SeleniumJavaScriptClickLiveTest { public void whenSearchForSeleniumArticles_thenReturnNotEmptyResults() { driver.get("https://baeldung.com"); String title = driver.getTitle(); - assertEquals("Baeldung | Java, Spring and Web Development tutorials", title); + assertEquals("Baeldung", title); wait.until(ExpectedConditions.elementToBeClickable(By.className("nav--menu_item_anchor"))); WebElement searchButton = driver.findElement(By.className("nav--menu_item_anchor")); clickElement(searchButton); - wait.until(ExpectedConditions.elementToBeClickable(By.id("search"))); - WebElement searchInput = driver.findElement(By.id("search")); - searchInput.sendKeys("Selenium"); + wait.until(ExpectedConditions.elementToBeClickable(By.id("menu-item-40489"))); + WebElement searchInput = driver.findElement(By.id("menu-item-40489")); - wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".btn-search"))); - WebElement seeSearchResultsButton = driver.findElement(By.cssSelector(".btn-search")); + wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(".nav--menu_item"))); + WebElement seeSearchResultsButton = driver.findElement(By.cssSelector(".nav--menu_item")); clickElement(seeSearchResultsButton); - wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("post"))); - int seleniumPostsCount = driver.findElements(By.className("post")) + wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.className("nav--menu_item_anchor"))); + int seleniumPostsCount = driver.findElements(By.className("nav--menu_item_anchor")) .size(); assertTrue(seleniumPostsCount > 0); } diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java index 8906f89fba..add0bf5ace 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/cookies/SeleniumCookiesJUnitLiveTest.java @@ -19,19 +19,24 @@ import org.junit.Test; import org.openqa.selenium.Cookie; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.WebDriverWait; public class SeleniumCookiesJUnitLiveTest { private WebDriver driver; private String navUrl; + private final String COOKIE = "SNS"; + @Before public void setUp() { System.setProperty("webdriver.gecko.driver", findFile("geckodriver.mac")); driver = new FirefoxDriver(); navUrl = "https://baeldung.com"; - driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5)); + driver.navigate().to(navUrl); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofMillis(1000)); + wait.until(d -> d.manage().getCookieNamed(COOKIE) != null); } private static String findFile(String filename) { @@ -50,7 +55,6 @@ public class SeleniumCookiesJUnitLiveTest { @Test public void whenNavigate_thenCookiesExist() { - driver.navigate().to(navUrl); Set cookies = driver.manage().getCookies(); assertThat(cookies, is(not(empty()))); @@ -58,35 +62,30 @@ public class SeleniumCookiesJUnitLiveTest { @Test public void whenNavigate_thenLpCookieExists() { - driver.navigate().to(navUrl); - Cookie lpCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie lpCookie = driver.manage().getCookieNamed(COOKIE); assertThat(lpCookie, is(not(nullValue()))); } @Test public void whenNavigate_thenLpCookieIsHasCorrectValue() { - driver.navigate().to(navUrl); - Cookie lpCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie lpCookie = driver.manage().getCookieNamed(COOKIE); - assertThat(lpCookie.getValue(), containsString("www.baeldung.com")); + assertThat(lpCookie.getValue(), containsString("1")); } @Test public void whenNavigate_thenLpCookieHasCorrectProps() { - driver.navigate().to(navUrl); - Cookie lpCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie lpCookie = driver.manage().getCookieNamed(COOKIE); - assertThat(lpCookie.getDomain(), equalTo(".baeldung.com")); + assertThat(lpCookie.getDomain(), equalTo("www.baeldung.com")); assertThat(lpCookie.getPath(), equalTo("/")); - assertThat(lpCookie.getExpiry(), is(not(nullValue()))); assertThat(lpCookie.isSecure(), equalTo(false)); assertThat(lpCookie.isHttpOnly(), equalTo(false)); } @Test public void whenAddingCookie_thenItIsPresent() { - driver.navigate().to(navUrl); Cookie cookie = new Cookie("foo", "bar"); driver.manage().addCookie(cookie); Cookie driverCookie = driver.manage().getCookieNamed("foo"); @@ -96,27 +95,25 @@ public class SeleniumCookiesJUnitLiveTest { @Test public void whenDeletingCookie_thenItIsAbsent() { - driver.navigate().to(navUrl); - Cookie lpCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie lpCookie = driver.manage().getCookieNamed("SNS"); assertThat(lpCookie, is(not(nullValue()))); driver.manage().deleteCookie(lpCookie); - Cookie deletedCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie deletedCookie = driver.manage().getCookieNamed(COOKIE); assertThat(deletedCookie, is(nullValue())); } @Test public void whenOverridingCookie_thenItIsUpdated() { - driver.navigate().to(navUrl); - Cookie lpCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie lpCookie = driver.manage().getCookieNamed(COOKIE); driver.manage().deleteCookie(lpCookie); - Cookie newLpCookie = new Cookie("lp_120073", "foo"); + Cookie newLpCookie = new Cookie(COOKIE, "foo"); driver.manage().addCookie(newLpCookie); - Cookie overriddenCookie = driver.manage().getCookieNamed("lp_120073"); + Cookie overriddenCookie = driver.manage().getCookieNamed(COOKIE); assertThat(overriddenCookie.getValue(), equalTo("foo")); } diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/setup/InvalidSetupLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/setup/InvalidSetupLiveTest.java index 09ab823828..dce4427ae9 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/setup/InvalidSetupLiveTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/setup/InvalidSetupLiveTest.java @@ -13,9 +13,9 @@ final class InvalidSetupLiveTest { @BeforeAll static void setup() { // Make sure the properties are cleared before the tests. - System.clearProperty("webdriver.chrome.driver"); - System.clearProperty("webdriver.gecko.driver"); - System.clearProperty("webdriver.edge.driver"); + System.setProperty("webdriver.chrome.driver", ""); + System.setProperty("webdriver.gecko.driver",""); + System.setProperty("webdriver.edge.driver",""); } @Test diff --git a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java index e4e89611d1..ed1aa60598 100644 --- a/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java +++ b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/webdriver/SeleniumWebDriverUnitTest.java @@ -16,7 +16,7 @@ public class SeleniumWebDriverUnitTest { private WebDriver driver; private static final String URL = "https://duckduckgo.com/"; - private static final String INPUT_ID = "search_form_input_homepage"; + private static final String INPUT_ID = "searchbox_input__bEGm3"; @BeforeEach public void setUp() { @@ -32,7 +32,7 @@ public class SeleniumWebDriverUnitTest { @Test public void givenDuckDuckGoHomePage_whenInputHelloWorld_thenInputValueIsHelloWorld() { driver.get(URL); - WebElement inputElement = driver.findElement(By.id(INPUT_ID)); + WebElement inputElement = driver.findElement(By.className(INPUT_ID)); inputElement.sendKeys(Keys.chord(Keys.CONTROL, "a"), Keys.DELETE); inputElement.sendKeys("Hello World!"); diff --git a/testing-modules/testing-assertions/README.md b/testing-modules/testing-assertions/README.md index 55a39ec606..37de3d4929 100644 --- a/testing-modules/testing-assertions/README.md +++ b/testing-modules/testing-assertions/README.md @@ -4,3 +4,4 @@ - [Assert Two Lists for Equality Ignoring Order in Java](https://www.baeldung.com/java-assert-lists-equality-ignore-order) - [Assert That a Java Optional Has a Certain Value](https://www.baeldung.com/java-optional-assert-value) - [Assert That an Object Is From a Specific Type](https://www.baeldung.com/java-assert-object-of-type) +- [Asserting Equality on Two Classes Without an equals() Method](https://www.baeldung.com/java-assert-equality-no-equals) diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 09f4291b78..1da53bd77e 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -24,6 +24,22 @@ ${commons-collections4.version} test + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + test + + + org.hamcrest + hamcrest + ${hamcrest.version} + test + + + 2.2 + + \ No newline at end of file diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Address.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Address.java new file mode 100644 index 0000000000..905dd44af9 --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Address.java @@ -0,0 +1,61 @@ +package com.baeldung.assertequals; + +public class Address { + + private Long id; + + private String city; + + private String street; + + private String country; + + public Address(final Long id, final String city, final String street, final String country) { + this.id = id; + this.city = city; + this.street = street; + this.country = country; + } + + public Long getId() { + return id; + } + + public void setId(final Long id) { + this.id = id; + } + + public String getCity() { + return city; + } + + public void setCity(final String city) { + this.city = city; + } + + public String getStreet() { + return street; + } + + public void setStreet(final String street) { + this.street = street; + } + + public String getCountry() { + return country; + } + + public void setCountry(final String country) { + this.country = country; + } + + @Override + public String toString() { + return "Address{" + + "id=" + id + + ", city='" + city + '\'' + + ", street='" + street + '\'' + + ", country='" + country + '\'' + + '}'; + } +} diff --git a/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Person.java b/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Person.java new file mode 100644 index 0000000000..8ea64357ec --- /dev/null +++ b/testing-modules/testing-assertions/src/main/java/com/baeldung/assertequals/Person.java @@ -0,0 +1,60 @@ +package com.baeldung.assertequals; + +public class Person { + + private Long id; + + private String firstName; + + private String lastName; + + private Address address; + + public Person(final Long id, final String firstName, final String lastName) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + } + + public Address getAddress() { + return address; + } + + public void setAddress(final Address address) { + this.address = address; + } + + public Long getId() { + return id; + } + + public void setId(final Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(final String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(final String lastName) { + this.lastName = lastName; + } + + @Override + public String toString() { + return "Person{" + + "id=" + id + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", address=" + address + + '}'; + } +} diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertequals/EqualityUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertequals/EqualityUnitTest.java new file mode 100644 index 0000000000..bf20e02a1d --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertequals/EqualityUnitTest.java @@ -0,0 +1,96 @@ +package com.baeldung.assertequals; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.Test; +import org.mockito.internal.matchers.apachecommons.ReflectionEquals; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.samePropertyValuesAs; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class EqualityUnitTest { + + @Test + void givenPersons_whenUseRecursiveComparison_thenOk() { + Person expected = new Person(1L, "Jane", "Doe"); + Address address1 = new Address(1L, "New York", "Sesame Street", "United States"); + expected.setAddress(address1); + + Person actual = new Person(1L, "Jane", "Doe"); + Address address2 = new Address(1L, "New York", "Sesame Street", "United States"); + actual.setAddress(address2); + + assertThat(actual).usingRecursiveComparison().isEqualTo(expected); + } + + @Test + void givenPersons_whenUseRecursiveComparisonIgnoringField_thenOk() { + Person expected = new Person(1L, "Jane", "Doe"); + Person actual = new Person(2L, "Jane", "Doe"); + + assertThat(actual) + .usingRecursiveComparison() + .ignoringFields("id") + .isEqualTo(expected); + } + + @Test + void givenPersons_whenCheckForSamePropertyValues_thenReturnOk() { + Person expected = new Person(1L, "Jane", "Doe"); + Address address1 = new Address(1L, "New York", "Sesame Street", "United States"); + expected.setAddress(address1); + + Person actual = new Person(1L, "Jane", "Doe"); + Address address2 = new Address(1L, "New York", "Sesame Street", "United States"); + actual.setAddress(address2); + + MatcherAssert.assertThat(actual, samePropertyValuesAs(expected, "address")); + MatcherAssert.assertThat(actual.getAddress(), samePropertyValuesAs(expected.getAddress())); + } + + @Test + void givenPerson_whenReflectionToStringBuilder_thenReturnOk() { + Person expected = new Person(1L, "Jane", "Doe"); + Address address1 = new Address(1L, "New York", "Sesame Street", "United States"); + expected.setAddress(address1); + + Person actual = new Person(1L, "Jane", "Doe"); + Address address2 = new Address(1L, "New York", "Sesame Street", "United States"); + actual.setAddress(address2); + + assertThat(ReflectionToStringBuilder.toString(actual, ToStringStyle.SHORT_PREFIX_STYLE)) + .isEqualTo(ReflectionToStringBuilder.toString(expected, ToStringStyle.SHORT_PREFIX_STYLE)); + } + + @Test + void givenPersons_whenEqualsBuilder_thenReturnTrue() { + Person expected = new Person(1L, "Jane", "Doe"); + Address address1 = new Address(1L, "New York", "Sesame Street", "United States"); + expected.setAddress(address1); + + Person actual = new Person(1L, "Jane", "Doe"); + Address address2 = new Address(1L, "New York", "Sesame Street", "United States"); + actual.setAddress(address2); + + assertTrue(EqualsBuilder.reflectionEquals(expected, actual, "address")); + assertTrue(EqualsBuilder.reflectionEquals(expected.getAddress(), actual.getAddress())); + } + + @Test + void givenPersons_whenReflectionEquals_thenReturnOk() { + Person expected = new Person(1L, "Jane", "Doe"); + Address address1 = new Address(1L, "New York", "Sesame Street", "United States"); + expected.setAddress(address1); + + Person actual = new Person(1L, "Jane", "Doe"); + Address address2 = new Address(1L, "New York", "Sesame Street", "United States"); + actual.setAddress(address2); + + assertTrue(new ReflectionEquals(expected, "address").matches(actual)); + assertTrue(new ReflectionEquals(expected.getAddress()).matches(actual.getAddress())); + } + +} diff --git a/testing-modules/testing-techniques/pom.xml b/testing-modules/testing-techniques/pom.xml index 5902047aeb..2e34a122ab 100644 --- a/testing-modules/testing-techniques/pom.xml +++ b/testing-modules/testing-techniques/pom.xml @@ -1,7 +1,7 @@ + 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"> testing-techniques 4.0.0 diff --git a/xml-2/pom.xml b/xml-2/pom.xml index 6b25d66b6a..d56fdd7165 100644 --- a/xml-2/pom.xml +++ b/xml-2/pom.xml @@ -68,7 +68,6 @@ - 2.1.3 2.14.1