diff --git a/.gitignore b/.gitignore index 21586748b7..b981a473f6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ .idea/ *.iml *.iws +out/ # Mac .DS_Store @@ -27,6 +28,9 @@ log/ target/ +# Gradle +.gradle/ + spring-openid/src/main/resources/application.properties .recommenders/ /spring-hibernate4/nbproject/ diff --git a/core-groovy-2/README.md b/core-groovy-2/README.md new file mode 100644 index 0000000000..f60bdb3cbe --- /dev/null +++ b/core-groovy-2/README.md @@ -0,0 +1,7 @@ +# Groovy + +## Relevant articles: + +- [String Matching in Groovy](http://www.baeldung.com/) +- [Groovy def Keyword] + diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml new file mode 100644 index 0000000000..77de9c8fc8 --- /dev/null +++ b/core-groovy-2/pom.xml @@ -0,0 +1,131 @@ + + + 4.0.0 + core-groovy-2 + 1.0-SNAPSHOT + core-groovy-2 + jar + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.codehaus.groovy + groovy + ${groovy.version} + + + org.codehaus.groovy + groovy-all + ${groovy-all.version} + pom + + + org.codehaus.groovy + groovy-dateutil + ${groovy.version} + + + org.codehaus.groovy + groovy-sql + ${groovy-sql.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + org.spockframework + spock-core + ${spock-core.version} + test + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + ${gmavenplus-plugin.version} + + + + addSources + addTestSources + compile + compileTests + + + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + maven-surefire-plugin + 2.20.1 + + false + + **/*Test.java + **/*Spec.java + + + + + + + + + central + http://jcenter.bintray.com + + + + + 1.0.0 + 2.5.6 + 2.5.6 + 2.5.6 + 2.4.0 + 1.1-groovy-2.4 + 1.6 + + + diff --git a/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy new file mode 100644 index 0000000000..310d97d3fd --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy @@ -0,0 +1,79 @@ +package com.baeldung.defkeyword + +import org.codehaus.groovy.runtime.NullObject +import org.codehaus.groovy.runtime.typehandling.GroovyCastException + +import groovy.transform.TypeChecked +import groovy.transform.TypeCheckingMode + +@TypeChecked +class DefUnitTest extends GroovyTestCase { + + def id + def firstName = "Samwell" + def listOfCountries = ['USA', 'UK', 'FRANCE', 'INDIA'] + + @TypeChecked(TypeCheckingMode.SKIP) + def multiply(x, y) { + return x*y + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testDefVariableDeclaration() { + + def list + assert list.getClass() == org.codehaus.groovy.runtime.NullObject + assert list.is(null) + + list = [1,2,4] + assert list instanceof ArrayList + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testTypeVariables() { + int rate = 200 + try { + rate = [12] //GroovyCastException + rate = "nill" //GroovyCastException + } catch(GroovyCastException) { + println "Cannot assign anything other than integer" + } + } + + @TypeChecked(TypeCheckingMode.SKIP) + void testDefVariableMultipleAssignment() { + def rate + assert rate == null + assert rate.getClass() == org.codehaus.groovy.runtime.NullObject + + rate = 12 + assert rate instanceof Integer + + rate = "Not Available" + assert rate instanceof String + + rate = [1, 4] + assert rate instanceof List + + assert divide(12, 3) instanceof BigDecimal + assert divide(1, 0) instanceof String + + } + + def divide(int x, int y) { + if(y==0) { + return "Should not divide by 0" + } else { + return x/y + } + } + + def greetMsg() { + println "Hello! I am Groovy" + } + + void testDefVsType() { + def int count + assert count instanceof Integer + } +} \ No newline at end of file diff --git a/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy b/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy new file mode 100644 index 0000000000..3865bc73fa --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy @@ -0,0 +1,44 @@ +package com.baeldung.strings + +import spock.lang.Specification + +import java.util.regex.Pattern + +class StringMatchingSpec extends Specification { + + def "pattern operator example"() { + given: "a pattern" + def p = ~'foo' + + expect: + p instanceof Pattern + + and: "you can use slash strings to avoid escaping of blackslash" + def digitPattern = ~/\d*/ + digitPattern.matcher('4711').matches() + } + + def "match operator example"() { + expect: + 'foobar' ==~ /.*oba.*/ + + and: "matching is strict" + !('foobar' ==~ /foo/) + } + + def "find operator example"() { + when: "using the find operator" + def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/ + + then: "will find groups" + matcher.size() == 2 + + and: "can access groups using array" + matcher[0][0] == 'foo and bar' + matcher[1][2] == 'buz' + + and: "you can use it as a predicate" + 'foobarbaz' =~ /bar/ + } + +} diff --git a/core-java-8-2/src/test/java/com/baeldung/UnitTest.java b/core-java-8-2/src/test/java/com/baeldung/UnitTest.java deleted file mode 100644 index 9757901f52..0000000000 --- a/core-java-8-2/src/test/java/com/baeldung/UnitTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Unit test for simple App. - */ -public class UnitTest { - /** - * Stub test - */ - @Test - public void givenPreconditions_whenCondition_shouldResult() { - assertTrue(true); - } -} diff --git a/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java new file mode 100644 index 0000000000..6964ba80e3 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java @@ -0,0 +1,165 @@ +package com.baeldung.filechannel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +public class FileChannelUnitTest { + + @Test + public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + FileInputStream fin = new FileInputStream("src/test/resources/test_read.in"); + FileChannel channel = fin.getChannel();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream();) { + + MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5); + + if (buff.hasRemaining()) { + byte[] data = new byte[buff.remaining()]; + buff.get(data); + assertEquals("world", new String(data, StandardCharsets.UTF_8)); + } + } + } + + @Test + public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + String file = "src/test/resources/test_write_using_filechannel.txt"; + try (RandomAccessFile writer = new RandomAccessFile(file, "rw"); + FileChannel channel = writer.getChannel();) { + ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); + + channel.write(buff); + + // now we verify whether the file was written correctly + RandomAccessFile reader = new RandomAccessFile(file, "r"); + assertEquals("Hello world", reader.readLine()); + reader.close(); + } + } + + @Test + public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException { + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw"); + FileChannel channel = reader.getChannel(); + FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) { + + assertNotNull(fileLock); + } + } + + @Test + public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel();) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.position()); + + channel.position(4); + assertEquals(4, channel.position()); + } + } + + @Test + public void whenGetFileSize_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel();) { + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.size()); + } + } + + @Test + public void whenTruncateFile_thenCorrect() throws IOException { + String input = "this is a test input"; + + FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt"); + FileChannel channel = fout.getChannel(); + + ByteBuffer buff = ByteBuffer.wrap(input.getBytes()); + channel.write(buff); + buff.flip(); + + channel = channel.truncate(5); + assertEquals(5, channel.size()); + + fout.close(); + channel.close(); + } +} diff --git a/core-java-io/src/test/resources/test_truncate.txt b/core-java-io/src/test/resources/test_truncate.txt new file mode 100644 index 0000000000..26d3b38cdd --- /dev/null +++ b/core-java-io/src/test/resources/test_truncate.txt @@ -0,0 +1 @@ +this \ No newline at end of file diff --git a/core-java-io/src/test/resources/test_write_using_filechannel.txt b/core-java-io/src/test/resources/test_write_using_filechannel.txt new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-io/src/test/resources/test_write_using_filechannel.txt @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-java-8-2/src/main/java/com/baeldung/anonymous/Book.java b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Book.java similarity index 100% rename from core-java-8-2/src/main/java/com/baeldung/anonymous/Book.java rename to core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Book.java diff --git a/core-java-8-2/src/main/java/com/baeldung/anonymous/Main.java b/core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Main.java similarity index 100% rename from core-java-8-2/src/main/java/com/baeldung/anonymous/Main.java rename to core-java-lang-oop-2/src/main/java/com/baeldung/anonymous/Main.java diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Entry.java b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Entry.java new file mode 100644 index 0000000000..07759ca9ba --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Entry.java @@ -0,0 +1,38 @@ +package com.baeldung.generics; + +import java.io.Serializable; + +public class Entry { + private String data; + private int rank; + + // non-generic constructor + public Entry(String data, int rank) { + this.data = data; + this.rank = rank; + } + + // generic constructor + public Entry(E element) { + this.data = element.toString(); + this.rank = element.getRank(); + } + + // getters and setters + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public int getRank() { + return rank; + } + + public void setRank(int rank) { + this.rank = rank; + } + +} diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/generics/GenericEntry.java b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/GenericEntry.java new file mode 100644 index 0000000000..27d3a44069 --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/GenericEntry.java @@ -0,0 +1,53 @@ +package com.baeldung.generics; + +import java.io.Serializable; +import java.util.Optional; + +public class GenericEntry { + private T data; + private int rank; + + // non-generic constructor + public GenericEntry(int rank) { + this.rank = rank; + } + + // generic constructor + public GenericEntry(T data, int rank) { + this.data = data; + this.rank = rank; + } + + // generic constructor with different type + public GenericEntry(E element) { + this.data = (T) element; + this.rank = element.getRank(); + } + + // generic constructor with different type and wild card + public GenericEntry(Optional optional) { + if (optional.isPresent()) { + this.data = (T) optional.get(); + this.rank = optional.get() + .getRank(); + } + } + + // getters and setters + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getRank() { + return rank; + } + + public void setRank(int rank) { + this.rank = rank; + } + +} diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/generics/MapEntry.java b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/MapEntry.java new file mode 100644 index 0000000000..3d626b2fa5 --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/MapEntry.java @@ -0,0 +1,34 @@ +package com.baeldung.generics; + +public class MapEntry { + private K key; + private V value; + + public MapEntry() { + super(); + } + + // generic constructor with two parameters + public MapEntry(K key, V value) { + this.key = key; + this.value = value; + } + + // getters and setters + public K getKey() { + return key; + } + + public void setKey(K key) { + this.key = key; + } + + public V getValue() { + return value; + } + + public void setValue(V value) { + this.value = value; + } + +} diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Product.java b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Product.java new file mode 100644 index 0000000000..bfc9f63071 --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Product.java @@ -0,0 +1,50 @@ +package com.baeldung.generics; + +import java.io.Serializable; + +public class Product implements Rankable, Serializable { + private String name; + private double price; + private int sales; + + public Product(String name, double price) { + this.name = name; + this.price = price; + } + + @Override + public int getRank() { + return sales; + } + + @Override + public String toString() { + return "Product [name=" + name + ", price=" + price + ", sales=" + sales + "]"; + } + + // getters and setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public int getSales() { + return sales; + } + + public void setSales(int sales) { + this.sales = sales; + } + +} diff --git a/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Rankable.java b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Rankable.java new file mode 100644 index 0000000000..72bda67d9d --- /dev/null +++ b/core-java-lang-oop-2/src/main/java/com/baeldung/generics/Rankable.java @@ -0,0 +1,5 @@ +package com.baeldung.generics; + +public interface Rankable { + public int getRank(); +} diff --git a/core-java-lang-oop-2/src/test/java/com/baeldung/generics/GenericConstructorUnitTest.java b/core-java-lang-oop-2/src/test/java/com/baeldung/generics/GenericConstructorUnitTest.java new file mode 100644 index 0000000000..60907bbfd3 --- /dev/null +++ b/core-java-lang-oop-2/src/test/java/com/baeldung/generics/GenericConstructorUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.generics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.Serializable; +import java.util.Optional; + +import org.junit.Test; + +public class GenericConstructorUnitTest { + + @Test + public void givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK() { + Entry entry = new Entry("sample", 1); + + assertEquals("sample", entry.getData()); + assertEquals(1, entry.getRank()); + } + + @Test + public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK() { + Product product = new Product("milk", 2.5); + product.setSales(30); + Entry entry = new Entry(product); + + assertEquals(product.toString(), entry.getData()); + assertEquals(30, entry.getRank()); + } + + @Test + public void givenNonGenericConstructor_whenCreateGenericEntry_thenOK() { + GenericEntry entry = new GenericEntry(1); + + assertNull(entry.getData()); + assertEquals(1, entry.getRank()); + } + + @Test + public void givenGenericConstructor_whenCreateGenericEntry_thenOK() { + GenericEntry entry = new GenericEntry("sample", 1); + + assertEquals("sample", entry.getData()); + assertEquals(1, entry.getRank()); + } + + @Test + public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK() { + Product product = new Product("milk", 2.5); + product.setSales(30); + GenericEntry entry = new GenericEntry(product); + + assertEquals(product, entry.getData()); + assertEquals(30, entry.getRank()); + } + + @Test + public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK() { + Product product = new Product("milk", 2.5); + product.setSales(30); + Optional optional = Optional.of(product); + GenericEntry entry = new GenericEntry(optional); + + assertEquals(product, entry.getData()); + assertEquals(30, entry.getRank()); + } + + @Test + public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK() { + MapEntry entry = new MapEntry("sample", 1); + + assertEquals("sample", entry.getKey()); + assertEquals(1, entry.getValue() + .intValue()); + } +} diff --git a/core-kotlin-2/build.gradle b/core-kotlin-2/build.gradle index b058e0ecad..1c52172404 100644 --- a/core-kotlin-2/build.gradle +++ b/core-kotlin-2/build.gradle @@ -5,7 +5,7 @@ version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.2.41' + ext.kotlin_version = '1.3.30' repositories { mavenCentral() @@ -26,8 +26,6 @@ sourceCompatibility = 1.8 compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } -kotlin { experimental { coroutines "enable" } } - repositories { mavenCentral() jcenter() @@ -39,10 +37,22 @@ sourceSets { srcDirs 'com/baeldung/ktor' } } +} +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } } dependencies { - compile "ch.qos.logback:logback-classic:1.2.1" - testCompile group: 'junit', name: 'junit', version: '4.12' -} \ No newline at end of file + implementation "ch.qos.logback:logback-classic:1.2.1" + implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}" + testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2' + testImplementation 'junit:junit:4.12' + testImplementation 'org.assertj:assertj-core:3.12.2' + testImplementation 'org.mockito:mockito-core:2.27.0' + testImplementation "org.jetbrains.kotlin:kotlin-test:${kotlin_version}" + testImplementation "org.jetbrains.kotlin:kotlin-test-junit5:${kotlin_version}" +} diff --git a/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar b/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar index 01b8bf6b1f..5c2d1cf016 100644 Binary files a/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar and b/core-kotlin-2/gradle/wrapper/gradle-wrapper.jar differ diff --git a/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties b/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties index 933b6473ce..5f1b1201a7 100644 --- a/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties +++ b/core-kotlin-2/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip diff --git a/core-kotlin-2/gradlew b/core-kotlin-2/gradlew index cccdd3d517..b0d6d0ab5d 100644 --- a/core-kotlin-2/gradlew +++ b/core-kotlin-2/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ 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="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/core-kotlin-2/gradlew.bat b/core-kotlin-2/gradlew.bat index f9553162f1..9991c50326 100644 --- a/core-kotlin-2/gradlew.bat +++ b/core-kotlin-2/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @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= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/core-kotlin-2/pom.xml b/core-kotlin-2/pom.xml index e329611593..be2f5fa68f 100644 --- a/core-kotlin-2/pom.xml +++ b/core-kotlin-2/pom.xml @@ -20,9 +20,21 @@ ${kotlin.version} - org.junit.platform - junit-platform-runner - ${junit.platform.version} + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + net.bytebuddy + byte-buddy + ${byte-buddy.version} test @@ -37,6 +49,12 @@ ${kotlin.version} test + + org.jetbrains.kotlin + kotlin-test-junit5 + ${kotlin.version} + test + @@ -69,10 +87,11 @@ - 1.2.71 - 1.1.1 - 5.2.0 + 1.3.30 + 5.4.2 + 2.27.0 + 1.9.12 3.10.0 - \ No newline at end of file + diff --git a/core-kotlin-2/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt b/core-kotlin-2/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt new file mode 100644 index 0000000000..c73096fce6 --- /dev/null +++ b/core-kotlin-2/src/test/kotlin/com/baeldung/console/ConsoleIOUnitTest.kt @@ -0,0 +1,79 @@ +package com.baeldung.console + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test +import org.mockito.Mockito.`when` +import org.mockito.Mockito.mock +import java.io.BufferedReader +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.Console +import java.io.InputStreamReader +import java.io.PrintStream +import java.util.* + + +class ConsoleIOUnitTest { + + @Test + fun givenText_whenPrint_thenPrintText() { + val expectedTest = "Hello from Kotlin" + val out = ByteArrayOutputStream() + System.setOut(PrintStream(out)) + + print(expectedTest) + out.flush() + val printedText = String(out.toByteArray()) + + assertThat(printedText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenRead_thenReadText() { + val expectedTest = "Hello from Kotlin" + val input = ByteArrayInputStream(expectedTest.toByteArray()) + System.setIn(input) + + val readText = readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithScanner_thenReadText() { + val expectedTest = "Hello from Kotlin" + val scanner = Scanner(ByteArrayInputStream(expectedTest.toByteArray())) + + val readText = scanner.nextLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithBufferedReader_thenReadText() { + val expectedTest = "Hello from Kotlin" + val reader = BufferedReader(InputStreamReader(ByteArrayInputStream(expectedTest.toByteArray()))) + + val readText = reader.readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @Test + fun givenInput_whenReadWithConsole_thenReadText() { + val expectedTest = "Hello from Kotlin" + val console = mock(Console::class.java) + `when`(console.readLine()).thenReturn(expectedTest) + + val readText = console.readLine() + + assertThat(readText).isEqualTo(expectedTest) + } + + @AfterEach + fun resetIO() { + System.setOut(System.out) + System.setIn(System.`in`) + } +} \ No newline at end of file diff --git a/core-kotlin-2/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/core-kotlin-2/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..ca6ee9cea8 --- /dev/null +++ b/core-kotlin-2/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/core-kotlin-io/.gitignore b/core-kotlin-io/.gitignore new file mode 100644 index 0000000000..f521947850 --- /dev/null +++ b/core-kotlin-io/.gitignore @@ -0,0 +1,11 @@ +/bin/ + +#ignore gradle +.gradle/ + + +#ignore build and generated files +build/ +node/ +target/ +out/ diff --git a/core-kotlin-io/README.md b/core-kotlin-io/README.md new file mode 100644 index 0000000000..c085c0653f --- /dev/null +++ b/core-kotlin-io/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [InputStream to String in Kotlin](https://www.baeldung.com/kotlin-inputstream-to-string) diff --git a/core-kotlin-io/pom.xml b/core-kotlin-io/pom.xml new file mode 100644 index 0000000000..2e21079d7f --- /dev/null +++ b/core-kotlin-io/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + core-kotlin-io + core-kotlin-io + jar + + + com.baeldung + parent-kotlin + 1.0.0-SNAPSHOT + ../parent-kotlin + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + + + + 1.2.71 + 1.1.1 + 5.2.0 + 3.10.0 + + + \ No newline at end of file diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt b/core-kotlin-io/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt similarity index 100% rename from core-kotlin-2/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt rename to core-kotlin-io/src/main/kotlin/com/baeldung/inputstream/InputStreamExtension.kt diff --git a/core-kotlin-2/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt b/core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt similarity index 93% rename from core-kotlin-2/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt rename to core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt index 3437ddb68a..d10d23bef0 100644 --- a/core-kotlin-2/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt +++ b/core-kotlin-io/src/test/kotlin/com/baeldung/inputstream/InputStreamToStringTest.kt @@ -8,7 +8,8 @@ import kotlin.test.assertEquals class InputStreamToStringTest { private val fileName = "src/test/resources/inputstream2string.txt" - private val fileFullContent = "Computer programming can be a hassle\r\n" + + private val endOfLine = System.lineSeparator() + private val fileFullContent = "Computer programming can be a hassle$endOfLine" + "It's like trying to take a defended castle" @Test @@ -46,7 +47,7 @@ class InputStreamToStringTest { } finally { reader.close() } - assertEquals(fileFullContent.replace("\r\n", ""), content.toString()) + assertEquals(fileFullContent.replace(endOfLine, ""), content.toString()) } diff --git a/core-kotlin-2/src/test/resources/inputstream2string.txt b/core-kotlin-io/src/test/resources/inputstream2string.txt similarity index 100% rename from core-kotlin-2/src/test/resources/inputstream2string.txt rename to core-kotlin-io/src/test/resources/inputstream2string.txt diff --git a/guava-collections-set/.gitignore b/guava-collections-set/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/guava-collections-set/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/guava-collections-set/pom.xml b/guava-collections-set/pom.xml new file mode 100644 index 0000000000..46dcae492d --- /dev/null +++ b/guava-collections-set/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + com.baeldung + guava-collections-set + 0.1.0-SNAPSHOT + guava-collections-set + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + guava-collections-set + + + + + 27.1-jre + + 3.6.1 + + + diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java new file mode 100644 index 0000000000..e74db29881 --- /dev/null +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMultiSetUnitTest.java @@ -0,0 +1,92 @@ +package org.baeldung.guava; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class GuavaMultiSetUnitTest { + + @Test + public void givenMultiSet_whenAddingValues_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.contains("Potter")).isTrue(); + assertThat(bookStore.count("Potter")).isEqualTo(3); + } + + @Test + public void givenMultiSet_whenRemovingValues_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + bookStore.remove("Potter"); + assertThat(bookStore.contains("Potter")).isTrue(); + assertThat(bookStore.count("Potter")).isEqualTo(1); + } + + @Test + public void givenMultiSet_whenSetCount_shouldReturnCorrectCount() { + Multiset bookStore = HashMultiset.create(); + bookStore.setCount("Potter", 50); + assertThat(bookStore.count("Potter")).isEqualTo(50); + } + + @Test + public void givenMultiSet_whenSettingNegativeCount_shouldThrowException() { + Multiset bookStore = HashMultiset.create(); + assertThatThrownBy(() -> bookStore.setCount("Potter", -1)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void givenMultiSet_whenSettingCountWithEmptySet_shouldBeSuccessful() { + Multiset bookStore = HashMultiset.create(); + assertThat(bookStore.setCount("Potter", 0, 2)).isTrue(); + } + + @Test + public void givenMultiSet_whenSettingCountWithCorrectValue_shouldBeSuccessful() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.setCount("Potter", 2, 52)).isTrue(); + } + + @Test + public void givenMultiSet_whenSettingCountWithIncorrectValue_shouldFail() { + Multiset bookStore = HashMultiset.create(); + bookStore.add("Potter"); + bookStore.add("Potter"); + + assertThat(bookStore.setCount("Potter", 5, 52)).isFalse(); + } + + @Test + public void givenMap_compareMultiSetOperations() { + Map bookStore = new HashMap<>(); + bookStore.put("Potter", 3); + + assertThat(bookStore.containsKey("Potter")).isTrue(); + assertThat(bookStore.get("Potter")).isEqualTo(3); + + bookStore.put("Potter", 2); + assertThat(bookStore.get("Potter")).isEqualTo(2); + + bookStore.put("Potter", null); + assertThat(bookStore.containsKey("Potter")).isTrue(); + + bookStore.put("Potter", -1); + assertThat(bookStore.containsKey("Potter")).isTrue(); + } +} \ No newline at end of file diff --git a/httpclient-simple/.gitignore b/httpclient-simple/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/httpclient-simple/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/httpclient-simple/README.md b/httpclient-simple/README.md new file mode 100644 index 0000000000..d1224359e0 --- /dev/null +++ b/httpclient-simple/README.md @@ -0,0 +1,11 @@ +========= +## HttpClient 4.x Cookbooks and Examples + +###The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + + +### Relevant Articles: + +- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code) +- [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl) \ No newline at end of file diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml new file mode 100644 index 0000000000..f3d00251d7 --- /dev/null +++ b/httpclient-simple/pom.xml @@ -0,0 +1,315 @@ + + 4.0.0 + com.baeldung + httpclient-simple + 0.1-SNAPSHOT + httpclient-simple + war + + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + + + + org.springframework.security + spring-security-web + ${spring.version} + + + org.springframework.security + spring-security-config + ${spring.version} + + + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-expression + ${spring.version} + + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + + org.springframework + spring-oxm + ${spring.version} + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + org.apache.httpcomponents + httpcore + ${httpcore.version} + + + commons-logging + commons-logging + + + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + fluent-hc + ${httpclient.version} + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + ${httpclient.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + org.apache.httpcomponents + httpasyncclient + ${httpasyncclient.version} + + + commons-logging + commons-logging + + + + + com.github.tomakehurst + wiremock + ${wiremock.version} + test + + + + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + + + + javax.servlet + jstl + ${jstl.version} + runtime + + + + + + com.google.guava + guava + ${guava.version} + + + + + + org.springframework + spring-test + ${spring.version} + test + + + + + httpclient-simple + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + + + + 8082 + + + + + + + + + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + + + + 1.2 + 3.1.0 + + 19.0 + 3.5 + 1.10 + 4.1.4 + + 2.5.1 + 4.4.11 + 4.5.8 + + 2.6 + 1.6.1 + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java b/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java new file mode 100644 index 0000000000..6e580e7a22 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/basic/MyBasicAuthenticationEntryPoint.java @@ -0,0 +1,30 @@ +package org.baeldung.basic; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +@Component +public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { + + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException { + response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\""); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + final PrintWriter writer = response.getWriter(); + writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage()); + } + + @Override + public void afterPropertiesSet() throws Exception { + setRealmName("Baeldung"); + super.afterPropertiesSet(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java b/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java new file mode 100644 index 0000000000..a2f51d343b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java @@ -0,0 +1,39 @@ +package org.baeldung.client; + +import java.net.URI; + +import org.apache.http.HttpHost; +import org.apache.http.client.AuthCache; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory { + + HttpHost host; + + public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) { + super(); + this.host = host; + } + + protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { + return createHttpContext(); + } + + private HttpContext createHttpContext() { + + AuthCache authCache = new BasicAuthCache(); + + BasicScheme basicAuth = new BasicScheme(); + authCache.put(host, basicAuth); + + BasicHttpContext localcontext = new BasicHttpContext(); + localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache); + return localcontext; + } +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java b/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java new file mode 100644 index 0000000000..3ed0bc82b7 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/RestTemplateFactory.java @@ -0,0 +1,44 @@ +package org.baeldung.client; + +import org.apache.http.HttpHost; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.support.BasicAuthenticationInterceptor; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class RestTemplateFactory implements FactoryBean, InitializingBean { + private RestTemplate restTemplate; + + public RestTemplateFactory() { + super(); + } + + // API + + @Override + public RestTemplate getObject() { + return restTemplate; + } + + @Override + public Class getObjectType() { + return RestTemplate.class; + } + + @Override + public boolean isSingleton() { + return true; + } + + @Override + public void afterPropertiesSet() { + HttpHost host = new HttpHost("localhost", 8082, "http"); + final ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth(host); + restTemplate = new RestTemplate(requestFactory); + restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor("user1", "user1Pass")); + } + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java b/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java new file mode 100644 index 0000000000..73e602855c --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/client/spring/ClientConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.client.spring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("org.baeldung.client") +public class ClientConfig { + + public ClientConfig() { + super(); + } + + // beans + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java b/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java new file mode 100644 index 0000000000..01e5b0b59d --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/filter/CustomFilter.java @@ -0,0 +1,18 @@ +package org.baeldung.filter; + +import org.springframework.web.filter.GenericFilterBean; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +public class CustomFilter extends GenericFilterBean { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + chain.doFilter(request, response); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java new file mode 100644 index 0000000000..7ca2a80c52 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java @@ -0,0 +1,49 @@ +package org.baeldung.filter; + +import org.baeldung.security.RestAuthenticationEntryPoint; +import org.springframework.beans.factory.annotation.Autowired; +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.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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +@Configuration +@EnableWebSecurity +public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user1") + .password(passwordEncoder().encode("user1Pass")) + .authorities("ROLE_USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/securityNone") + .permitAll() + .anyRequest() + .authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint); + + http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java b/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java new file mode 100644 index 0000000000..698052fa2b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/security/MySavedRequestAwareAuthenticationSuccessHandler.java @@ -0,0 +1,48 @@ +package org.baeldung.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.util.StringUtils; + +public class MySavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private RequestCache requestCache = new HttpSessionRequestCache(); + + @Override + public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws ServletException, IOException { + final SavedRequest savedRequest = requestCache.getRequest(request, response); + + if (savedRequest == null) { + super.onAuthenticationSuccess(request, response, authentication); + + return; + } + final String targetUrlParameter = getTargetUrlParameter(); + if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) { + requestCache.removeRequest(request, response); + super.onAuthenticationSuccess(request, response, authentication); + + return; + } + + clearAuthenticationAttributes(request); + + // Use the DefaultSavedRequest URL + // final String targetUrl = savedRequest.getRedirectUrl(); + // logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl); + // getRedirectStrategy().sendRedirect(request, response, targetUrl); + } + + public void setRequestCache(final RequestCache requestCache) { + this.requestCache = requestCache; + } +} diff --git a/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java b/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000000..77aa32ff97 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/security/RestAuthenticationEntryPoint.java @@ -0,0 +1,23 @@ +package org.baeldung.security; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +/** + * The Entry Point will not redirect to any sort of Login - it will return the 401 + */ +@Component +public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + } + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java new file mode 100644 index 0000000000..4ce80dab9f --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.spring; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +@Configuration +@ImportResource({ "classpath:webSecurityConfig.xml" }) +@ComponentScan("org.baeldung.security") +public class SecSecurityConfig { + + public SecSecurityConfig() { + super(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java b/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java new file mode 100644 index 0000000000..5876e1307b --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/spring/WebConfig.java @@ -0,0 +1,30 @@ +package org.baeldung.spring; + +import java.util.List; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +@ComponentScan("org.baeldung.web") +public class WebConfig implements WebMvcConfigurer { + + public WebConfig() { + super(); + } + + // beans + + @Override + public void configureMessageConverters(final List> converters) { + converters.add(new MappingJackson2HttpMessageConverter()); + } + + // + +} \ No newline at end of file diff --git a/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java b/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java new file mode 100644 index 0000000000..2bc314baa2 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/controller/BarController.java @@ -0,0 +1,31 @@ +package org.baeldung.web.controller; + +import org.baeldung.web.dto.Bar; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/bars") +public class BarController { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public BarController() { + super(); + } + + // API + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + public Bar findOne(@PathVariable("id") final Long id) { + return new Bar(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java b/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java new file mode 100644 index 0000000000..b50edb2dcf --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/controller/FooController.java @@ -0,0 +1,33 @@ +package org.baeldung.web.controller; + +import org.baeldung.web.dto.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping(value = "/foos") +public class FooController { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public FooController() { + super(); + } + + // API + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + @PreAuthorize("hasRole('ROLE_USER')") + public Foo findOne(@PathVariable("id") final Long id) { + return new Foo(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java b/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java new file mode 100644 index 0000000000..d33e39a823 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/dto/Bar.java @@ -0,0 +1,14 @@ +package org.baeldung.web.dto; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Bar implements Serializable { + + public Bar() { + super(); + } + +} diff --git a/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java b/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..09c1dac933 --- /dev/null +++ b/httpclient-simple/src/main/java/org/baeldung/web/dto/Foo.java @@ -0,0 +1,14 @@ +package org.baeldung.web.dto; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Foo implements Serializable { + + public Foo() { + super(); + } + +} diff --git a/httpclient-simple/src/main/resources/logback.xml b/httpclient-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/httpclient-simple/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/resources/webSecurityConfig.xml b/httpclient-simple/src/main/resources/webSecurityConfig.xml new file mode 100644 index 0000000000..a93dc841b6 --- /dev/null +++ b/httpclient-simple/src/main/resources/webSecurityConfig.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml b/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml new file mode 100644 index 0000000000..1dbff70b83 --- /dev/null +++ b/httpclient-simple/src/main/webapp/WEB-INF/api-servlet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/httpclient-simple/src/main/webapp/WEB-INF/web.xml b/httpclient-simple/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..83b4aeb0a7 --- /dev/null +++ b/httpclient-simple/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,43 @@ + + + + Spring Security Custom Application + + + + contextClass + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + contextConfigLocation + org.baeldung.spring + + + + org.springframework.web.context.ContextLoaderListener + + + + + api + org.springframework.web.servlet.DispatcherServlet + 1 + + + api + /api/* + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + + \ No newline at end of file diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java similarity index 88% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java index 2a668f827a..286ee3c900 100644 --- a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/ClientLiveTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/client/ClientLiveTest.java @@ -33,13 +33,13 @@ public class ClientLiveTest { @Test public final void whenSecuredRestApiIsConsumed_then200OK() { - final ResponseEntity responseEntity = secureRestTemplate.exchange("http://localhost:8082/spring-security-rest-basic-auth/api/foos/1", HttpMethod.GET, null, Foo.class); + final ResponseEntity responseEntity = secureRestTemplate.exchange("http://localhost:8082/httpclient-simple/api/foos/1", HttpMethod.GET, null, Foo.class); assertThat(responseEntity.getStatusCode().value(), is(200)); } @Test(expected = ResourceAccessException.class) public final void whenHttpsUrlIsConsumed_thenException() { - final String urlOverHttps = "https://localhost:8443/spring-security-rest-basic-auth/api/bars/1"; + final String urlOverHttps = "https://localhost:8443/httpclient-simple/api/bars/1"; final ResponseEntity response = new RestTemplate().exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); } diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java b/httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java similarity index 63% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java rename to httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java index 104129b663..53f259c21d 100644 --- a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/client/RestClientLiveManualTest.java @@ -8,19 +8,24 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLContext; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; +import org.apache.http.ssl.SSLContexts; import org.junit.Ignore; import org.junit.Test; import org.springframework.http.HttpMethod; @@ -34,14 +39,14 @@ import org.springframework.web.client.RestTemplate; * */ public class RestClientLiveManualTest { - final String urlOverHttps = "http://localhost:8082/spring-security-rest-basic-auth/api/bars/1"; + final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1"; // tests // old httpClient will throw UnsupportedOperationException @Ignore @Test - public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException() throws GeneralSecurityException { + public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_1() throws GeneralSecurityException { final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); final CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient(); @@ -57,6 +62,29 @@ public class RestClientLiveManualTest { final ResponseEntity response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class); assertThat(response.getStatusCode().value(), equalTo(200)); } + + // new httpClient : 4.4 and above + @Test + public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException_2() throws GeneralSecurityException { + + final TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; + final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + final Registry socketFactoryRegistry = RegistryBuilder. create() + .register("https", sslsf) + .register("http", new PlainConnectionSocketFactory()) + .build(); + + final BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager(socketFactoryRegistry); + final CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setConnectionManager(connectionManager) + .build(); + + final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + final ResponseEntity response = new RestTemplate(requestFactory).exchange(urlOverHttps, HttpMethod.GET, null, String.class); + assertThat(response.getStatusCode().value(), equalTo(200)); + } @Test public final void givenAcceptingAllCertificatesUsing4_4_whenHttpsUrlIsConsumed_thenCorrect() throws ClientProtocolException, IOException { diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java similarity index 82% rename from httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java index 4eadfe24d5..9e95905c70 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java +++ b/httpclient-simple/src/test/java/org/baeldung/httpclient/HttpsClientSslLiveTest.java @@ -1,32 +1,31 @@ package org.baeldung.httpclient; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.conn.ClientConnectionManager; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.ssl.SSLContexts; -import org.junit.Test; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; -import java.io.IOException; -import java.security.GeneralSecurityException; - import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +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.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; +import org.junit.Test; + /** * This test requires a localhost server over HTTPS
* It should only be manually run, not part of the automated build @@ -50,16 +49,22 @@ public class HttpsClientSslLiveTest { .getStatusCode(), equalTo(200)); } - @SuppressWarnings("deprecation") @Test public final void givenHttpClientPre4_3_whenAcceptingAllCertificates_thenCanConsumeHttpsUriWithSelfSignedCertificate() throws IOException, GeneralSecurityException { final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; - final SSLSocketFactory sf = new SSLSocketFactory(acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); - final SchemeRegistry registry = new SchemeRegistry(); - registry.register(new Scheme("https", 443, sf)); - final ClientConnectionManager ccm = new PoolingClientConnectionManager(registry); + + final SSLContext sslContext = SSLContexts.custom() + .loadTrustMaterial(null, acceptingTrustStrategy) + .build(); - final CloseableHttpClient httpClient = new DefaultHttpClient(ccm); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + Registry socketFactoryRegistry = RegistryBuilder. create().register("https", sslsf).build(); + PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + + final CloseableHttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setConnectionManager(clientConnectionManager) + .build(); final HttpGet getMethod = new HttpGet(HOST_WITH_SSL); final HttpResponse response = httpClient.execute(getMethod); @@ -76,10 +81,9 @@ public class HttpsClientSslLiveTest { .loadTrustMaterial(null, acceptingTrustStrategy) .build(); - final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); final CloseableHttpClient httpClient = HttpClients.custom() - .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .setSSLSocketFactory(sslsf) .build(); diff --git a/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java new file mode 100644 index 0000000000..fd38b95cbe --- /dev/null +++ b/httpclient-simple/src/test/java/org/baeldung/httpclient/ResponseUtil.java @@ -0,0 +1,26 @@ +package org.baeldung.httpclient; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; + +import java.io.IOException; + +public final class ResponseUtil { + private ResponseUtil() { + } + + public static void closeResponse(CloseableHttpResponse response) throws IOException { + if (response == null) { + return; + } + + try { + final HttpEntity entity = response.getEntity(); + if (entity != null) { + entity.getContent().close(); + } + } finally { + response.close(); + } + } +} diff --git a/httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java b/httpclient-simple/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java similarity index 100% rename from httpclient/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java rename to httpclient-simple/src/test/java/org/baeldung/httpclient/base/HttpClientBasicLiveTest.java diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/test/LiveTestSuite.java b/httpclient-simple/src/test/java/org/baeldung/test/LiveTestSuite.java similarity index 100% rename from spring-security-rest-basic-auth/src/test/java/org/baeldung/test/LiveTestSuite.java rename to httpclient-simple/src/test/java/org/baeldung/test/LiveTestSuite.java diff --git a/httpclient-simple/src/test/resources/.gitignore b/httpclient-simple/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/httpclient-simple/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/httpclient/README.md b/httpclient/README.md index c5956068c6..ce98d7e72e 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -8,7 +8,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [HttpClient 4 – Send Custom Cookie](http://www.baeldung.com/httpclient-4-cookies) -- [HttpClient 4 – Get the Status Code](http://www.baeldung.com/httpclient-status-code) - [HttpClient 4 – Cancel Request](http://www.baeldung.com/httpclient-cancel-request) - [HttpClient 4 Cookbook](http://www.baeldung.com/httpclient4) - [Unshorten URLs with HttpClient](http://www.baeldung.com/unshorten-url-httpclient) diff --git a/httpclient/pom.xml b/httpclient/pom.xml index c9f9808ede..def3a05816 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -122,11 +122,10 @@ 19.0 3.5 1.10 - 4.1.2 + 4.1.4 2.5.1 - 4.4.5 - 4.5.3 + 4.5.8 1.6.1 diff --git a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java index d39697c0a9..47a587885e 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -4,7 +4,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import java.io.IOException; -import java.security.cert.X509Certificate; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -18,8 +17,7 @@ import org.apache.http.client.CredentialsProvider; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; +import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.BasicCredentialsProvider; @@ -31,6 +29,7 @@ import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; +import org.apache.http.ssl.SSLContexts; import org.junit.Test; public class HttpAsyncClientLiveTest { @@ -104,7 +103,7 @@ public class HttpAsyncClientLiveTest { final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); - final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).setSSLContext(sslContext).build(); + final CloseableHttpAsyncClient client = HttpAsyncClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).build(); client.start(); final HttpGet request = new HttpGet(HOST_WITH_SSL); diff --git a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java index 0f8ebefe6c..cf945098db 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -327,7 +327,8 @@ public class HttpClientConnectionManagementLiveTest { // 8.1 public final void whenHttpClientChecksStaleConns_thenNoExceptions() { poolingConnManager = new PoolingHttpClientConnectionManager(); - client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build()).setConnectionManager(poolingConnManager).build(); + poolingConnManager.setValidateAfterInactivity(1000); + client = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().build()).setConnectionManager(poolingConnManager).build(); } @Test diff --git a/jackson-2/pom.xml b/jackson-2/pom.xml index ddbcb81dcc..6b973dd6f5 100644 --- a/jackson-2/pom.xml +++ b/jackson-2/pom.xml @@ -22,6 +22,20 @@ ${jackson.version} + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.9.8 + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.8 + + diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java new file mode 100644 index 0000000000..2075b7879b --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/Order.java @@ -0,0 +1,68 @@ +package com.baeldung.jackson.entities; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public class Order { + private String orderNo; + private LocalDate date; + private String customerName; + private List orderLines; + + public Order() { + + } + + public Order(String orderNo, LocalDate date, String customerName, List orderLines) { + super(); + this.orderNo = orderNo; + this.date = date; + this.customerName = customerName; + this.orderLines = orderLines; + } + + public String getOrderNo() { + return orderNo; + } + + public void setOrderNo(String orderNo) { + this.orderNo = orderNo; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public List getOrderLines() { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + return orderLines; + } + + public void setOrderLines(List orderLines) { + if (orderLines == null) { + orderLines = new ArrayList<>(); + } + this.orderLines = orderLines; + } + + @Override + public String toString() { + return "Order [orderNo=" + orderNo + ", date=" + date + ", customerName=" + customerName + ", orderLines=" + orderLines + "]"; + } + +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java b/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java new file mode 100644 index 0000000000..858d094dd1 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/entities/OrderLine.java @@ -0,0 +1,49 @@ +package com.baeldung.jackson.entities; + +import java.math.BigDecimal; + +public class OrderLine { + private String item; + private int quantity; + private BigDecimal unitPrice; + + public OrderLine() { + + } + + public OrderLine(String item, int quantity, BigDecimal unitPrice) { + super(); + this.item = item; + this.quantity = quantity; + this.unitPrice = unitPrice; + } + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + + @Override + public String toString() { + return "OrderLine [item=" + item + ", quantity=" + quantity + ", unitPrice=" + unitPrice + "]"; + } +} diff --git a/jackson-2/src/main/resources/orderInput.yaml b/jackson-2/src/main/resources/orderInput.yaml new file mode 100644 index 0000000000..0aaa6186a2 --- /dev/null +++ b/jackson-2/src/main/resources/orderInput.yaml @@ -0,0 +1,11 @@ +orderNo: A001 +date: 2019-04-17 +customerName: Customer, Joe +orderLines: + - item: No. 9 Sprockets + quantity: 12 + unitPrice: 1.23 + - item: Widget (10mm) + quantity: 4 + unitPrice: 3.45 + \ No newline at end of file diff --git a/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java new file mode 100644 index 0000000000..3ed84db60e --- /dev/null +++ b/jackson-2/src/test/java/com/baeldung/jackson/yaml/YamlUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.jackson.yaml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.jackson.entities.Order; +import com.baeldung.jackson.entities.OrderLine; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; + +public class YamlUnitTest { + private ObjectMapper mapper; + + @Before + public void setup() { + mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER)); + mapper.findAndRegisterModules(); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + } + + @Test + public void givenYamlInput_ObjectCreated() throws JsonParseException, JsonMappingException, IOException { + Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class); + assertEquals("A001", order.getOrderNo()); + assertEquals(LocalDate.parse("2019-04-17", DateTimeFormatter.ISO_DATE), order.getDate()); + assertEquals("Customer, Joe", order.getCustomerName()); + assertEquals(2, order.getOrderLines() + .size()); + } + + @Test + public void givenYamlObject_FileWritten() throws JsonGenerationException, JsonMappingException, IOException { + List lines = new ArrayList<>(); + lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP))); + lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP))); + Order order = new Order( + "B-9910", + LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE), + "Customer, Jane", + lines); + mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order); + + File outputYaml = new File("src/main/resources/orderOutput.yaml"); + assertTrue(outputYaml.exists()); + } +} diff --git a/jackson-simple/.gitignore b/jackson-simple/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/jackson-simple/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/jackson-simple/README.md b/jackson-simple/README.md new file mode 100644 index 0000000000..be647e22d5 --- /dev/null +++ b/jackson-simple/README.md @@ -0,0 +1,13 @@ +========= +### Jackson Articles that are also part of the e-book + +###The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: +- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization) +- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties) +- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations) +- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial) +- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields) +- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property) diff --git a/jackson-simple/pom.xml b/jackson-simple/pom.xml new file mode 100644 index 0000000000..5023ad87b6 --- /dev/null +++ b/jackson-simple/pom.xml @@ -0,0 +1,131 @@ + + 4.0.0 + jackson-simple + 0.1-SNAPSHOT + jackson-simple + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + commons-io + commons-io + ${commons-io.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.version} + + + + com.fasterxml.jackson.module + jackson-module-jsonSchema + ${jackson.version} + + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${jackson.version} + + + + joda-time + joda-time + ${joda-time.version} + + + + com.google.code.gson + gson + ${gson.version} + + + + + + io.rest-assured + json-schema-validator + ${rest-assured.version} + test + + + + io.rest-assured + json-path + ${rest-assured.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + jackson-simple + + + src/main/resources + true + + + + + + + 3.8 + 2.10 + 2.8.5 + 4.2 + + + 3.1.1 + 3.11.0 + + + diff --git a/jackson-simple/src/main/resources/logback.xml b/jackson-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/jackson-simple/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/AliasBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/AliasBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCreator.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithCustomAnnotation.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithFilter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithGetter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithIgnore.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/BeanWithInject.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/ExtendableBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/MyBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/MyBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/PrivateBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/RawBean.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/RawBean.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UnwrappedUser.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/UserWithIgnoreType.java diff --git a/jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java b/jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/annotation/Zoo.java rename to jackson-simple/src/test/java/com/baeldung/jackson/annotation/Zoo.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java new file mode 100644 index 0000000000..25de4a8f7a --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIdentity.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class ItemWithIdentity { + public int id; + public String itemName; + public UserWithIdentity owner; + + public ItemWithIdentity() { + super(); + } + + public ItemWithIdentity(final int id, final String itemName, final UserWithIdentity owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java new file mode 100644 index 0000000000..910ccec174 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithIgnore.java @@ -0,0 +1,17 @@ +package com.baeldung.jackson.bidirection; + +public class ItemWithIgnore { + public int id; + public String itemName; + public UserWithIgnore owner; + + public ItemWithIgnore() { + super(); + } + + public ItemWithIgnore(final int id, final String itemName, final UserWithIgnore owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java new file mode 100644 index 0000000000..0ca8d721e8 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/ItemWithRef.java @@ -0,0 +1,21 @@ +package com.baeldung.jackson.bidirection; + +import com.fasterxml.jackson.annotation.JsonManagedReference; + +public class ItemWithRef { + public int id; + public String itemName; + + @JsonManagedReference + public UserWithRef owner; + + public ItemWithRef() { + super(); + } + + public ItemWithRef(final int id, final String itemName, final UserWithRef owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java new file mode 100644 index 0000000000..db83a09389 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIdentity.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") +public class UserWithIdentity { + public int id; + public String name; + public List userItems; + + public UserWithIdentity() { + super(); + } + + public UserWithIdentity(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIdentity item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java new file mode 100644 index 0000000000..857a373cc5 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithIgnore.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class UserWithIgnore { + public int id; + public String name; + + @JsonIgnore + public List userItems; + + public UserWithIgnore() { + super(); + } + + public UserWithIgnore(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithIgnore item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java new file mode 100644 index 0000000000..3de03fc651 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/bidirection/UserWithRef.java @@ -0,0 +1,28 @@ +package com.baeldung.jackson.bidirection; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonBackReference; + +public class UserWithRef { + public int id; + public String name; + + @JsonBackReference + public List userItems; + + public UserWithRef() { + super(); + } + + public UserWithRef(final int id, final String name) { + this.id = id; + this.name = name; + userItems = new ArrayList(); + } + + public void addItem(final ItemWithRef item) { + userItems.add(item); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java new file mode 100644 index 0000000000..90c7d9fbac --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateDeserializer.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.date; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class CustomDateDeserializer extends StdDeserializer { + + private static final long serialVersionUID = -5451717385630622729L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateDeserializer() { + this(null); + } + + public CustomDateDeserializer(final Class vc) { + super(vc); + } + + @Override + public Date deserialize(final JsonParser jsonparser, final DeserializationContext context) throws IOException, JsonProcessingException { + final String date = jsonparser.getText(); + try { + return formatter.parse(date); + } catch (final ParseException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java new file mode 100644 index 0000000000..d840e1940f --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/CustomDateSerializer.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.date; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class CustomDateSerializer extends StdSerializer { + + private static final long serialVersionUID = -2894356342227378312L; + private SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + + public CustomDateSerializer() { + this(null); + } + + public CustomDateSerializer(final Class t) { + super(t); + } + + @Override + public void serialize(final Date value, final JsonGenerator gen, final SerializerProvider arg2) throws IOException, JsonProcessingException { + gen.writeString(formatter.format(value)); + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java new file mode 100644 index 0000000000..607e694cef --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithFormat.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +public class EventWithFormat { + public String name; + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") + public Date eventDate; + + public EventWithFormat() { + super(); + } + + public EventWithFormat(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java new file mode 100644 index 0000000000..c359b5c846 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/date/EventWithSerializer.java @@ -0,0 +1,31 @@ +package com.baeldung.jackson.date; + +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class EventWithSerializer { + public String name; + + @JsonDeserialize(using = CustomDateDeserializer.class) + @JsonSerialize(using = CustomDateSerializer.class) + public Date eventDate; + + public EventWithSerializer() { + super(); + } + + public EventWithSerializer(final String name, final Date eventDate) { + this.name = name; + this.eventDate = eventDate; + } + + public Date getEventDate() { + return eventDate; + } + + public String getName() { + return name; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java new file mode 100644 index 0000000000..eaba9a7173 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/deserialization/ItemDeserializerOnClass.java @@ -0,0 +1,41 @@ +package com.baeldung.jackson.deserialization; + +import java.io.IOException; + +import com.baeldung.jackson.dtos.ItemWithSerializer; +import com.baeldung.jackson.dtos.User; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.IntNode; + +public class ItemDeserializerOnClass extends StdDeserializer { + + private static final long serialVersionUID = 5579141241817332594L; + + public ItemDeserializerOnClass() { + this(null); + } + + public ItemDeserializerOnClass(final Class vc) { + super(vc); + } + + /** + * {"id":1,"itemNr":"theItem","owner":2} + */ + @Override + public ItemWithSerializer deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { + final JsonNode node = jp.getCodec() + .readTree(jp); + final int id = (Integer) ((IntNode) node.get("id")).numberValue(); + final String itemName = node.get("itemName") + .asText(); + final int userId = (Integer) ((IntNode) node.get("owner")).numberValue(); + + return new ItemWithSerializer(id, itemName, new User(userId, null)); + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java new file mode 100644 index 0000000000..6fce2bc88e --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/Item.java @@ -0,0 +1,32 @@ +package com.baeldung.jackson.dtos; + +public class Item { + public int id; + public String itemName; + public User owner; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java new file mode 100644 index 0000000000..aea9aa770d --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ItemWithSerializer.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.dtos; + +import com.baeldung.jackson.deserialization.ItemDeserializerOnClass; +import com.baeldung.jackson.serialization.ItemSerializerOnClass; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +@JsonSerialize(using = ItemSerializerOnClass.class) +@JsonDeserialize(using = ItemDeserializerOnClass.class) +public class ItemWithSerializer { + public final int id; + public final String itemName; + public final User owner; + + public ItemWithSerializer(final int id, final String itemName, final User owner) { + this.id = id; + this.itemName = itemName; + this.owner = owner; + } + + // API + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public User getOwner() { + return owner; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java new file mode 100644 index 0000000000..49cf07baea --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDto.java @@ -0,0 +1,54 @@ +package com.baeldung.jackson.dtos; + +public class MyDto { + + private String stringValue; + private int intValue; + private boolean booleanValue; + + public MyDto() { + super(); + } + + public MyDto(final String stringValue, final int intValue, final boolean booleanValue) { + super(); + + this.stringValue = stringValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + // API + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public void setIntValue(final int intValue) { + this.intValue = intValue; + } + + public boolean isBooleanValue() { + return booleanValue; + } + + public void setBooleanValue(final boolean booleanValue) { + this.booleanValue = booleanValue; + } + + // + + @Override + public String toString() { + return "MyDto [stringValue=" + stringValue + ", intValue=" + intValue + ", booleanValue=" + booleanValue + "]"; + } + +} diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoFieldNameChanged.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoIncludeNonDefault.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessors.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoNoAccessorsAndFieldVisibility.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithFilter.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyDtoWithSpecialField.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/MyMixInForIgnoreType.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java new file mode 100644 index 0000000000..2418e8070d --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/User.java @@ -0,0 +1,26 @@ +package com.baeldung.jackson.dtos; + +public class User { + public int id; + public String name; + + public User() { + super(); + } + + public User(final int id, final String name) { + this.id = id; + this.name = name; + } + + // API + + public int getId() { + return id; + } + + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreField.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreFieldByName.java diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java rename to jackson-simple/src/test/java/com/baeldung/jackson/dtos/ignore/MyDtoIgnoreNull.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java new file mode 100644 index 0000000000..69c476d8a5 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/dtos/withEnum/DistanceEnumWithValue.java @@ -0,0 +1,29 @@ +package com.baeldung.jackson.dtos.withEnum; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum DistanceEnumWithValue { + KILOMETER("km", 1000), MILE("miles", 1609.34), METER("meters", 1), INCH("inches", 0.0254), CENTIMETER("cm", 0.01), MILLIMETER("mm", 0.001); + + private String unit; + private final double meters; + + private DistanceEnumWithValue(String unit, double meters) { + this.unit = unit; + this.meters = meters; + } + + @JsonValue + public double getMeters() { + return meters; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + +} \ No newline at end of file diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java new file mode 100644 index 0000000000..d879c16e6a --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRoot.java @@ -0,0 +1,18 @@ +package com.baeldung.jackson.exception; + +import com.fasterxml.jackson.annotation.JsonRootName; + +@JsonRootName(value = "user") +public class UserWithRoot { + public int id; + public String name; + + public UserWithRoot() { + super(); + } + + public UserWithRoot(final int id, final String name) { + this.id = id; + this.name = name; + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java b/jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java rename to jackson-simple/src/test/java/com/baeldung/jackson/exception/UserWithRootNamespace.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java new file mode 100644 index 0000000000..26d20d4847 --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Item.java @@ -0,0 +1,36 @@ +package com.baeldung.jackson.jsonview; + +import com.fasterxml.jackson.annotation.JsonView; + +public class Item { + @JsonView(Views.Public.class) + public int id; + + @JsonView(Views.Public.class) + public String itemName; + + @JsonView(Views.Internal.class) + public String ownerName; + + public Item() { + super(); + } + + public Item(final int id, final String itemName, final String ownerName) { + this.id = id; + this.itemName = itemName; + this.ownerName = ownerName; + } + + public int getId() { + return id; + } + + public String getItemName() { + return itemName; + } + + public String getOwnerName() { + return ownerName; + } +} diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java new file mode 100644 index 0000000000..65950b7f9f --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/jsonview/Views.java @@ -0,0 +1,9 @@ +package com.baeldung.jackson.jsonview; + +public class Views { + public static class Public { + } + + public static class Internal extends Public { + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarDeserializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/CustomCarSerializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/JavaReadWriteJsonExampleUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/SerializationDeserializationFeatureUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Car.java diff --git a/jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java b/jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java rename to jackson-simple/src/test/java/com/baeldung/jackson/objectmapper/dto/Request.java diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializer.java diff --git a/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java new file mode 100644 index 0000000000..1fdf44e17c --- /dev/null +++ b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/ItemSerializerOnClass.java @@ -0,0 +1,32 @@ +package com.baeldung.jackson.serialization; + +import java.io.IOException; + +import com.baeldung.jackson.dtos.ItemWithSerializer; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +public class ItemSerializerOnClass extends StdSerializer { + + private static final long serialVersionUID = -1760959597313610409L; + + public ItemSerializerOnClass() { + this(null); + } + + public ItemSerializerOnClass(final Class t) { + super(t); + } + + @Override + public final void serialize(final ItemWithSerializer value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + jgen.writeNumberField("id", value.id); + jgen.writeStringField("itemName", value.itemName); + jgen.writeNumberField("owner", value.owner.id); + jgen.writeEndObject(); + } + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java b/jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java rename to jackson-simple/src/test/java/com/baeldung/jackson/serialization/MyDtoNullKeySerializer.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonAnnotationUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java b/jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java similarity index 100% rename from jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java rename to jackson-simple/src/test/java/com/baeldung/jackson/test/JacksonSerializationUnitTest.java diff --git a/jackson-simple/src/test/resources/.gitignore b/jackson-simple/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/jackson-simple/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/jackson/README.md b/jackson/README.md index eeb8f1b874..794ddc04d9 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -6,9 +6,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Jackson Ignore Properties on Marshalling](http://www.baeldung.com/jackson-ignore-properties-on-serialization) - [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array) -- [Jackson Unmarshalling json with Unknown Properties](http://www.baeldung.com/jackson-deserialize-json-unknown-properties) - [Jackson – Custom Serializer](http://www.baeldung.com/jackson-custom-serialization) - [Getting Started with Custom Deserialization in Jackson](http://www.baeldung.com/jackson-deserialization) - [Jackson Exceptions – Problems and Solutions](http://www.baeldung.com/jackson-exception) @@ -17,10 +15,8 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Jackson JSON Tutorial](http://www.baeldung.com/jackson) - [Jackson – Working with Maps and nulls](http://www.baeldung.com/jackson-map-null-values-or-null-key) - [Jackson – Decide What Fields Get Serialized/Deserialized](http://www.baeldung.com/jackson-field-serializable-deserializable-or-not) -- [Jackson Annotation Examples](http://www.baeldung.com/jackson-annotations) - [Working with Tree Model Nodes in Jackson](http://www.baeldung.com/jackson-json-node-tree-model) - [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson) -- [Intro to the Jackson ObjectMapper](http://www.baeldung.com/jackson-object-mapper-tutorial) - [XML Serialization and Deserialization with Jackson](http://www.baeldung.com/jackson-xml-serialization-and-deserialization) - [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations) - [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance) @@ -31,9 +27,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Jackson – JsonMappingException (No serializer found for class)](http://www.baeldung.com/jackson-jsonmappingexception) - [How To Serialize Enums as JSON Objects with Jackson](http://www.baeldung.com/jackson-serialize-enums) - [Jackson – Marshall String to JsonNode](http://www.baeldung.com/jackson-json-to-jsonnode) -- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields) - [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array) -- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property) - [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria) - [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values) - [Convert XML to JSON Using Jackson](https://www.baeldung.com/jackson-convert-xml-json) diff --git a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java index 6be2f29baa..e783c67f5b 100644 --- a/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java +++ b/jackson/src/test/java/com/baeldung/jackson/test/UnitTestSuite.java @@ -12,8 +12,6 @@ import org.junit.runners.Suite; ,JacksonDeserializationUnitTest.class ,JacksonDeserializationUnitTest.class ,JacksonPrettyPrintUnitTest.class - ,JacksonSerializationIgnoreUnitTest.class - ,JacksonSerializationUnitTest.class ,SandboxUnitTest.class ,JacksonFieldUnitTest.class }) // @formatter:on diff --git a/parent-kotlin/pom.xml b/parent-kotlin/pom.xml index 7a3a8b10ca..86ab45ecb1 100644 --- a/parent-kotlin/pom.xml +++ b/parent-kotlin/pom.xml @@ -202,10 +202,10 @@ - 1.3.10 + 1.3.30 1.0.0 0.9.5 - 3.11.0 - 1.2.0 + 3.12.0 + 1.3.2 diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml new file mode 100644 index 0000000000..11caf67bf1 --- /dev/null +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -0,0 +1,52 @@ + + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + hibernate-mapping + 1.0.0-SNAPSHOT + 4.0.0 + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2database.version} + + + + + hibernate-mapping + + + src/test/resources + true + + + + + + 5.3.7.Final + 1.4.196 + 3.8.0 + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java new file mode 100644 index 0000000000..7411edd225 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -0,0 +1,64 @@ +package com.baeldung.hibernate; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + + private HibernateUtil() { + } + + public static SessionFactory getSessionFactory(Strategy strategy) { + if (sessionFactory == null) { + sessionFactory = buildSessionFactory(strategy); + } + return sessionFactory; + } + + private static SessionFactory buildSessionFactory(Strategy strategy) { + try { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + + for (Class entityClass : strategy.getEntityClasses()) { + metadataSources.addAnnotatedClass(entityClass); + } + + Metadata metadata = metadataSources.getMetadataBuilder() + .build(); + + return metadata.getSessionFactoryBuilder() + .build(); + } catch (IOException ex) { + throw new ExceptionInInitializerError(ex); + } + } + + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource("hibernate.properties"); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java new file mode 100644 index 0000000000..75f10ed583 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java @@ -0,0 +1,31 @@ +package com.baeldung.hibernate; + + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public enum Strategy { + //See that the classes belongs to different packages + MAP_KEY_COLUMN_BASED(Collections.singletonList(com.baeldung.hibernate.persistmaps.mapkeycolumn.Order.class)), + MAP_KEY_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkey.Item.class, + com.baeldung.hibernate.persistmaps.mapkey.Order.class)), + MAP_KEY_JOIN_COLUMN_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller.class, + com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item.class, + com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order.class)), + MAP_KEY_ENUMERATED_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order.class, + com.baeldung.hibernate.persistmaps.mapkey.Item.class)), + MAP_KEY_TEMPORAL_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeytemporal.Order.class, + com.baeldung.hibernate.persistmaps.mapkey.Item.class)); + + + private List> entityClasses; + + Strategy(List> entityClasses) { + this.entityClasses = entityClasses; + } + + public List> getEntityClasses() { + return entityClasses; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java new file mode 100644 index 0000000000..b7f3cef9a2 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/ItemType.java @@ -0,0 +1,6 @@ +package com.baeldung.hibernate.persistmaps; + +public enum ItemType { + JEANS, + TSHIRTS +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java new file mode 100644 index 0000000000..385ffe93ea --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Item.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps.mapkey; + +import com.baeldung.hibernate.persistmaps.ItemType; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "item") +public class Item { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String itemName; + + @Column(name = "price") + private double itemPrice; + + @Enumerated(EnumType.STRING) + @Column(name = "item_type") + private ItemType itemType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_on") + private Date createdOn; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public double getItemPrice() { + return itemPrice; + } + + public void setItemPrice(double itemPrice) { + this.itemPrice = itemPrice; + } + + public ItemType getItemType() { + return itemType; + } + + public void setItemType(ItemType itemType) { + this.itemType = itemType; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Item item = (Item) o; + return id == item.id && + Double.compare(item.itemPrice, itemPrice) == 0 && + Objects.equals(itemName, item.itemName) && + itemType == item.itemType && + Objects.equals(createdOn, item.createdOn); + } + + @Override + public int hashCode() { + return Objects.hash(id, itemName, itemPrice, itemType, createdOn); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java new file mode 100644 index 0000000000..8409cacd6b --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/Order.java @@ -0,0 +1,44 @@ +package com.baeldung.hibernate.persistmaps.mapkey; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKey; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKey(name = "itemName") + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java new file mode 100644 index 0000000000..fa092060da --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeycolumn/Order.java @@ -0,0 +1,43 @@ +package com.baeldung.hibernate.persistmaps.mapkeycolumn; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.MapKeyColumn; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @ElementCollection + @CollectionTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}) + @MapKeyColumn(name = "item_name") + @Column(name = "price") + private Map itemPriceMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemPriceMap() { + return itemPriceMap; + } + + public void setItemPriceMap(Map itemPriceMap) { + this.itemPriceMap = itemPriceMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java new file mode 100644 index 0000000000..e1f62599b8 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyenumerated/Order.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.persistmaps.mapkeyenumerated; + +import com.baeldung.hibernate.persistmaps.ItemType; +import com.baeldung.hibernate.persistmaps.mapkey.Item; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyEnumerated; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyEnumerated(EnumType.STRING) + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java new file mode 100644 index 0000000000..97bbd5b539 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Item.java @@ -0,0 +1,112 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import com.baeldung.hibernate.persistmaps.ItemType; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "item") +public class Item { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String itemName; + + @Column(name = "price") + private double itemPrice; + + @Column(name = "item_type") + @Enumerated(EnumType.STRING) + private ItemType itemType; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_on") + private Date createdOn; + + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "seller_id") + private Seller seller; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + public double getItemPrice() { + return itemPrice; + } + + public void setItemPrice(double itemPrice) { + this.itemPrice = itemPrice; + } + + public ItemType getItemType() { + return itemType; + } + + public void setItemType(ItemType itemType) { + this.itemType = itemType; + } + + public Date getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Date createdOn) { + this.createdOn = createdOn; + } + + public Seller getSeller() { + return seller; + } + + public void setSeller(Seller seller) { + this.seller = seller; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Item item = (Item) o; + return id == item.id && + Double.compare(item.itemPrice, itemPrice) == 0 && + Objects.equals(itemName, item.itemName) && + itemType == item.itemType && + Objects.equals(createdOn, item.createdOn) && + Objects.equals(seller, item.seller); + } + + @Override + public int hashCode() { + + return Objects.hash(id, itemName, itemPrice, itemType, createdOn, seller); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java new file mode 100644 index 0000000000..d680d84501 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Order.java @@ -0,0 +1,44 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyJoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyJoinColumn(name = "seller_id") + private Map sellerItemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getSellerItemMap() { + return sellerItemMap; + } + + public void setSellerItemMap(Map sellerItemMap) { + this.sellerItemMap = sellerItemMap; + } +} \ No newline at end of file diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java new file mode 100644 index 0000000000..15b08e9fe6 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeyjoincolumn/Seller.java @@ -0,0 +1,51 @@ +package com.baeldung.hibernate.persistmaps.mapkeyjoincolumn; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Objects; + +@Entity +@Table(name = "seller") +public class Seller { + + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @Column(name = "name") + private String sellerName; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSellerName() { + return sellerName; + } + + public void setSellerName(String sellerName) { + this.sellerName = sellerName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Seller seller = (Seller) o; + return Objects.equals(sellerName, seller.sellerName); + } + + @Override + public int hashCode() { + + return Objects.hash(sellerName); + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java new file mode 100644 index 0000000000..be602c1e9f --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkeytemporal/Order.java @@ -0,0 +1,48 @@ +package com.baeldung.hibernate.persistmaps.mapkeytemporal; + +import com.baeldung.hibernate.persistmaps.mapkey.Item; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MapKeyTemporal; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TemporalType; +import java.util.Date; +import java.util.Map; + +@Entity +@Table(name = "orders") +public class Order { + @Id + @GeneratedValue + @Column(name = "id") + private int id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinTable(name = "order_item_mapping", joinColumns = {@JoinColumn(name = "order_id", referencedColumnName = "id")}, + inverseJoinColumns = {@JoinColumn(name = "item_id", referencedColumnName = "id")}) + @MapKeyTemporal(TemporalType.TIMESTAMP) + private Map itemMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getItemMap() { + return itemMap; + } + + public void setItemMap(Map itemMap) { + this.itemMap = itemMap; + } +} diff --git a/persistence-modules/hibernate-mapping/src/main/resources/logback.xml b/persistence-modules/hibernate-mapping/src/main/resources/logback.xml new file mode 100644 index 0000000000..26beb6d5b4 --- /dev/null +++ b/persistence-modules/hibernate-mapping/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/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java new file mode 100644 index 0000000000..acd77ee382 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyColumnIntegrationTest.java @@ -0,0 +1,79 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkeycolumn.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyColumnIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_COLUMN_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyColumn_thenPersistMap() { + Map itemPriceMap = new HashMap<>(); + itemPriceMap.put("Wrangler Jeans", 150.0); + itemPriceMap.put("Lee Jeans", 180.0); + + + Order order = new Order(); + order.setItemPriceMap(itemPriceMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(); + } + + private void assertInsertedData() { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemPriceMap = order.getItemPriceMap(); + assertNotNull(itemPriceMap); + assertEquals(itemPriceMap.size(), 2); + assertEquals((Double) 150.0, itemPriceMap.get("Wrangler Jeans")); + assertEquals((Double) 180.0, itemPriceMap.get("Lee Jeans")); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java new file mode 100644 index 0000000000..221aa7b1d7 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyEnumeratedIntegrationTest.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkeyenumerated.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyEnumeratedIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_ENUMERATED_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() { + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + + Map itemMap = new HashMap<>(); + itemMap.put(item1.getItemType(), item1); + itemMap.put(item2.getItemType(), item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1, item2); + } + + private void assertInsertedData(Item expectedItem1, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get(ItemType.JEANS)); + assertEquals(expectedItem2, itemMap.get(ItemType.TSHIRTS)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java new file mode 100644 index 0000000000..b500deb78e --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyIntegrationTest.java @@ -0,0 +1,95 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkey.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKey_thenPersistMap() { + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + + Map itemMap = new HashMap<>(); + itemMap.put(item1.getItemName(), item1); + itemMap.put(item2.getItemName(), item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1, item2); + } + + private void assertInsertedData(Item expectedItem1, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get("Wrangler Jeans")); + assertEquals(expectedItem2, itemMap.get("Armani Tshirts")); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java new file mode 100644 index 0000000000..88b22f5c99 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyJoinColumnIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Item; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Order; +import com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyJoinColumnIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_JOIN_COLUMN_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyJoinColumn_thenPersistMap() { + Seller seller1 = new Seller(); + seller1.setSellerName("Walmart"); + + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(Date.from(Instant.ofEpochSecond(1554926573))); + item1.setSeller(seller1); + + + Seller seller2 = new Seller(); + seller2.setSellerName("Amazon"); + + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(Date.from(Instant.ofEpochSecond(1554890573))); + item2.setSeller(seller2); + + Map itemSellerMap = new HashMap<>(); + itemSellerMap.put(seller1, item1); + itemSellerMap.put(seller2, item2); + + Order order = new Order(); + order.setSellerItemMap(itemSellerMap); + + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(seller1, item1, seller2, item2); + } + + private void assertInsertedData(Seller seller1, Item expectedItem1, Seller seller2, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map sellerItemMap = order.getSellerItemMap(); + assertNotNull(sellerItemMap); + assertEquals(2, sellerItemMap.size()); + assertEquals(expectedItem1, sellerItemMap.get(seller1)); + assertEquals(expectedItem2, sellerItemMap.get(seller2)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} + diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java new file mode 100644 index 0000000000..7117cad22f --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/persistmaps/MapKeyTemporalIntegrationTest.java @@ -0,0 +1,96 @@ +package com.baeldung.hibernate.persistmaps; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.Item; +import com.baeldung.hibernate.persistmaps.mapkeytemporal.Order; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.time.Instant; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class MapKeyTemporalIntegrationTest { + private static SessionFactory sessionFactory; + + private Session session; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_TEMPORAL_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void givenData_whenInsertUsingMapKeyEnumerated_thenPersistMap() { + Date item1CreatedOn = Date.from(Instant.ofEpochSecond(1554926573)); + Item item1 = new Item(); + item1.setItemName("Wrangler Jeans"); + item1.setItemPrice(150.0); + item1.setItemType(ItemType.JEANS); + item1.setCreatedOn(item1CreatedOn); + + + Date item2CreatedOn = Date.from(Instant.ofEpochSecond(1554890573)); + Item item2 = new Item(); + item2.setItemName("Armani Tshirts"); + item2.setItemPrice(180.0); + item2.setItemType(ItemType.TSHIRTS); + item2.setCreatedOn(item2CreatedOn); + + Map itemMap = new HashMap<>(); + itemMap.put(item1CreatedOn, item1); + itemMap.put(item2CreatedOn, item2); + + Order order = new Order(); + order.setItemMap(itemMap); + + session.persist(order); + session.getTransaction().commit(); + + assertInsertedData(item1CreatedOn, item1, item2CreatedOn, item2); + } + + private void assertInsertedData(Date item1CreatedOn, Item expectedItem1, Date item2CreatedOn, Item expectedItem2) { + @SuppressWarnings("unchecked") + List orderList = session.createQuery("FROM Order").list(); + + assertNotNull(orderList); + assertEquals(1, orderList.size()); + + Order order = orderList.get(0); + + Map itemMap = order.getItemMap(); + assertNotNull(itemMap); + assertEquals(2, itemMap.size()); + assertEquals(expectedItem1, itemMap.get(item1CreatedOn)); + assertEquals(expectedItem2, itemMap.get(item2CreatedOn)); + + } + + @After + public void tearDown() { + session.close(); + } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } +} diff --git a/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties new file mode 100644 index 0000000000..c22da2496b --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/resources/hibernate.properties @@ -0,0 +1,10 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop + diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 47c733d8a7..ee55325b20 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -22,6 +22,7 @@ hbase hibernate5 hibernate-ogm + hibernate-mapping influxdb java-cassandra java-cockroachdb diff --git a/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql b/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql new file mode 100644 index 0000000000..2d7b446005 --- /dev/null +++ b/persistence-modules/spring-boot-h2/spring-boot-h2-database/src/main/resources/data.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS billionaires; + +CREATE TABLE billionaires ( + id INT AUTO_INCREMENT PRIMARY KEY, + first_name VARCHAR(250) NOT NULL, + last_name VARCHAR(250) NOT NULL, + career VARCHAR(250) DEFAULT NULL +); + +INSERT INTO billionaires (first_name, last_name, career) VALUES +('Aliko', 'Dangote', 'Billionaire Industrialist'), +('Bill', 'Gates', 'Billionaire Tech Entrepreneur'), +('Folrunsho', 'Alakija', 'Billionaire Oil Magnate'); \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java index 547a905d91..c5c77be56f 100644 --- a/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java +++ b/persistence-modules/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java @@ -1,13 +1,9 @@ package com.baeldung.boot.config; -import java.util.Properties; - -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @@ -17,10 +13,17 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + @Configuration @EnableJpaRepositories(basePackages = { "com.baeldung.boot.repository", "com.baeldung.repository" }) @PropertySource("classpath:persistence-generic-entity.properties") @EnableTransactionManagement +@Profile("default") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project + //this demo project is showcasing several ways to achieve the same end, and class-level + //Profile annotations are only necessary because the different techniques are sharing a project public class H2JpaConfig { @Autowired diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java index 0227458987..d7bb44e133 100644 --- a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java +++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java @@ -1,8 +1,9 @@ package com.baeldung; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - +import com.baeldung.boot.Application; +import com.baeldung.boot.domain.GenericEntity; +import com.baeldung.boot.repository.GenericEntityRepository; +import com.baeldung.config.H2TestProfileJPAConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,13 +11,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.boot.Application; -import com.baeldung.boot.config.H2JpaConfig; -import com.baeldung.boot.domain.GenericEntity; -import com.baeldung.boot.repository.GenericEntityRepository; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; @RunWith(SpringRunner.class) -@SpringBootTest(classes = { Application.class, H2JpaConfig.class }) +@SpringBootTest(classes = { Application.class, H2TestProfileJPAConfig.class }) @ActiveProfiles("test") public class SpringBootProfileIntegrationTest { @Autowired diff --git a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java index e0678bcf47..f73000a10e 100644 --- a/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java +++ b/persistence-modules/spring-boot-persistence/src/test/java/com/baeldung/config/H2TestProfileJPAConfig.java @@ -1,10 +1,5 @@ package com.baeldung.config; -import java.util.Properties; - -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,9 +12,16 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + @Configuration @EnableJpaRepositories(basePackages = { "com.baeldung.repository", "com.baeldung.boot.repository" }) @EnableTransactionManagement +@Profile("test") //only required to allow H2JpaConfig and H2TestProfileJPAConfig to coexist in same project + //this demo project is showcasing several ways to achieve the same end, and class-level + //Profile annotations are only necessary because the different techniques are sharing a project public class H2TestProfileJPAConfig { @Autowired diff --git a/persistence-modules/spring-data-jpa-2/pom.xml b/persistence-modules/spring-data-jpa-2/pom.xml index 8e46112659..251007ba6d 100644 --- a/persistence-modules/spring-data-jpa-2/pom.xml +++ b/persistence-modules/spring-data-jpa-2/pom.xml @@ -1,12 +1,13 @@ + 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 - com.baeldung + + com.baeldung spring-data-jpa-2 - spring-data-jpa - + spring-data-jpa + parent-boot-2 com.baeldung @@ -19,12 +20,22 @@ org.springframework.boot spring-boot-starter-data-jpa - + com.h2database h2 - + + + com.fasterxml.jackson.core + jackson-databind + + + + org.springframework + spring-oxm + + \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java new file mode 100644 index 0000000000..24348d31c5 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/config/JpaPopulators.java @@ -0,0 +1,35 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.data.repository.init.Jackson2RepositoryPopulatorFactoryBean; +import org.springframework.data.repository.init.UnmarshallerRepositoryPopulatorFactoryBean; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +import com.baeldung.entity.Fruit; + +@Configuration +public class JpaPopulators { + + @Bean + public Jackson2RepositoryPopulatorFactoryBean getRespositoryPopulator() throws Exception { + Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean(); + factory.setResources(new Resource[] { new ClassPathResource("fruit-data.json") }); + return factory; + } + + @Bean + public UnmarshallerRepositoryPopulatorFactoryBean repositoryPopulator() { + + Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller(); + unmarshaller.setClassesToBeBound(Fruit.class); + + UnmarshallerRepositoryPopulatorFactoryBean factory = new UnmarshallerRepositoryPopulatorFactoryBean(); + factory.setUnmarshaller(unmarshaller); + factory.setResources(new Resource[] { new ClassPathResource("apple-fruit-data.xml"), new ClassPathResource("guava-fruit-data.xml") }); + return factory; + } + +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java new file mode 100644 index 0000000000..203cff1e35 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/Company.java @@ -0,0 +1,71 @@ +package com.baeldung.embeddable.model; + +import javax.persistence.AttributeOverride; +import javax.persistence.AttributeOverrides; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Company { + + @Id + @GeneratedValue + private Integer id; + + private String name; + + private String address; + + private String phone; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")), + @AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")), + @AttributeOverride( name = "phone", column = @Column(name = "contact_phone")) + }) + private ContactPerson contactPerson; + + 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; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public ContactPerson getContactPerson() { + return contactPerson; + } + + public void setContactPerson(ContactPerson contactPerson) { + this.contactPerson = contactPerson; + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java new file mode 100644 index 0000000000..561da80878 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/model/ContactPerson.java @@ -0,0 +1,38 @@ +package com.baeldung.embeddable.model; + +import javax.persistence.Embeddable; + +@Embeddable +public class ContactPerson { + + private String firstName; + + private String lastName; + + private String phone; + + 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; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java new file mode 100644 index 0000000000..f456b15652 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/embeddable/repositories/CompanyRepository.java @@ -0,0 +1,18 @@ +package com.baeldung.embeddable.repositories; + +import com.baeldung.embeddable.model.Company; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CompanyRepository extends JpaRepository { + + List findByContactPersonFirstName(String firstName); + + @Query("SELECT C FROM Company C WHERE C.contactPerson.firstName = ?1") + List findByContactPersonFirstNameWithJPQL(String firstName); + + @Query(value = "SELECT * FROM company WHERE contact_first_name = ?1", nativeQuery = true) + List findByContactPersonFirstNameWithNativeQuery(String firstName); +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java index f82022e67e..d45ac33db8 100644 --- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Fruit.java @@ -2,7 +2,9 @@ package com.baeldung.entity; import javax.persistence.Entity; import javax.persistence.Id; +import javax.xml.bind.annotation.XmlRootElement; +@XmlRootElement @Entity public class Fruit { diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml b/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml new file mode 100644 index 0000000000..d87ae28f1e --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/apple-fruit-data.xml @@ -0,0 +1,7 @@ + + + + 1 + apple + red + diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json b/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json new file mode 100644 index 0000000000..6dc44e2586 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/fruit-data.json @@ -0,0 +1,14 @@ +[ + { + "_class": "com.baeldung.entity.Fruit", + "name": "apple", + "color": "red", + "id": 1 + }, + { + "_class": "com.baeldung.entity.Fruit", + "name": "guava", + "color": "green", + "id": 2 + } +] \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml b/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml new file mode 100644 index 0000000000..ffd75bb4bb --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/resources/guava-fruit-data.xml @@ -0,0 +1,7 @@ + + + + 2 + guava + green + diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java new file mode 100644 index 0000000000..b4c365a2d9 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/embeddable/EmbeddableIntegrationTest.java @@ -0,0 +1,125 @@ +package com.baeldung.embeddable; + +import com.baeldung.Application; +import com.baeldung.embeddable.model.Company; +import com.baeldung.embeddable.model.ContactPerson; +import com.baeldung.embeddable.repositories.CompanyRepository; +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.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {Application.class}) +public class EmbeddableIntegrationTest { + + @Autowired + private CompanyRepository companyRepository; + + @Test + @Transactional + public void whenInsertingCompany_thenEmbeddedContactPersonDetailsAreMapped() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("First"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + Company result = companyRepository.getOne(company.getId()); + + assertEquals("Company", result.getName()); + assertEquals("1st street", result.getAddress()); + assertEquals("987-654-321", result.getPhone()); + assertEquals("First", result.getContactPerson().getFirstName()); + assertEquals("Last", result.getContactPerson().getLastName()); + assertEquals("123-456-789", result.getContactPerson().getPhone()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttribute_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("Name"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstName("Name"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstName("FirstName"); + + assertEquals(0, result.size()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttributeWithJPQL_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("@QueryName"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstNameWithJPQL("@QueryName"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstNameWithJPQL("FirstName"); + + assertEquals(0, result.size()); + } + + @Test + @Transactional + public void whenFindingCompanyByContactPersonAttributeWithNativeQuery_thenCompanyIsReturnedProperly() { + ContactPerson contactPerson = new ContactPerson(); + contactPerson.setFirstName("NativeQueryName"); + contactPerson.setLastName("Last"); + contactPerson.setPhone("123-456-789"); + + Company company = new Company(); + company.setName("Company"); + company.setAddress("1st street"); + company.setPhone("987-654-321"); + company.setContactPerson(contactPerson); + + companyRepository.save(company); + + List result = companyRepository.findByContactPersonFirstNameWithNativeQuery("NativeQueryName"); + + assertEquals(1, result.size()); + + result = companyRepository.findByContactPersonFirstNameWithNativeQuery("FirstName"); + + assertEquals(0, result.size()); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java new file mode 100644 index 0000000000..29ef52dcef --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java @@ -0,0 +1,38 @@ +package com.baeldung.repository; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +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.junit4.SpringRunner; + +import com.baeldung.entity.Fruit; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class FruitPopulatorTest { + + @Autowired + private FruitRepository fruitRepository; + + @Test + public void givenFruitJsonPopulatorThenShouldInsertRecordOnStart() { + + List fruits = fruitRepository.findAll(); + assertEquals("record count is not matching", 2, fruits.size()); + + fruits.forEach(fruit -> { + if (1 == fruit.getId()) { + assertEquals("apple", fruit.getName()); + assertEquals("red", fruit.getColor()); + } else if (2 == fruit.getId()) { + assertEquals("guava", fruit.getName()); + assertEquals("green", fruit.getColor()); + } + }); + } +} diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java index b2d145899e..6c6c145942 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/passenger/PassengerRepository.java @@ -9,6 +9,8 @@ interface PassengerRepository extends JpaRepository, CustomPass Passenger findFirstByOrderBySeatNumberAsc(); + Passenger findTopByOrderBySeatNumberAsc(); + List findByOrderBySeatNumberAsc(); List findByLastNameOrderBySeatNumberAsc(String lastName); diff --git a/pom.xml b/pom.xml index d57fa1694e..0de4a36336 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 1.0.0-SNAPSHOT parent-modules pom - + lombok-custom @@ -233,7 +233,7 @@ ${maven-war-plugin.version} - + com.vackosar.gitflowincrementalbuilder @@ -376,12 +376,13 @@ cdi checker-plugin core-groovy + core-groovy-2 - + core-java-8 core-java-8-2 - core-java-lambdas + core-java-lambdas core-java-arrays @@ -404,7 +405,7 @@ core-scala couchbase custom-pmd - + dagger data-structures ddd @@ -412,13 +413,13 @@ disruptor dozer drools - dubbo - + dubbo + ethereum - + feign flyway-cdi-extension - + geotools google-cloud google-web-toolkit @@ -432,17 +433,19 @@ guava-modules guice - + hazelcast helidon httpclient + httpclient-simple hystrix - + image-processing immutables jackson jackson-2 + jackson-simple java-collections-conversions java-collections-maps java-collections-maps-2 @@ -484,7 +487,7 @@ kotlin-libraries - + libraries libraries-2 @@ -511,8 +514,8 @@ mustache mybatis - - + + optaplanner orika osgi @@ -522,9 +525,9 @@ performance-tests protobuffer - + persistence-modules - + rabbitmq ratpack @@ -536,16 +539,17 @@ rule-engines rsocket rxjava - rxjava-2 + rxjava-2 software-security/sql-injection-samples - + tensorflow-java spring-boot-flowable - + spring-security-kerberos + - + default-second @@ -579,12 +583,12 @@ parent-spring-5 parent-java parent-kotlin - + saas spark-java - + spring-4 - + spring-5 spring-5-webflux spring-5-data-reactive @@ -595,7 +599,7 @@ spring-5-reactive-security spring-5-security spring-5-security-oauth - + spring-activiti spring-akka spring-all @@ -605,7 +609,7 @@ spring-apache-camel spring-batch spring-bom - + spring-boot spring-boot-admin spring-boot-angular @@ -615,6 +619,7 @@ spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-crud spring-boot-ctx-fluent spring-boot-custom-starter @@ -633,41 +638,41 @@ spring-boot-testing spring-boot-vue spring-boot-libraries - + spring-cloud spring-cloud-bus spring-cloud-data-flow - + spring-core spring-cucumber - + spring-data-rest spring-data-rest-querydsl spring-dispatcher-servlet spring-drools - + spring-ehcache spring-ejb spring-exceptions - + spring-freemarker - + spring-groovy - + spring-integration - + spring-jenkins-pipeline spring-jersey spring-jinq spring-jms spring-jooq - + spring-kafka spring-katharsis - + spring-ldap - + spring-mobile spring-mockito spring-mvc-forms-jsp @@ -679,12 +684,12 @@ spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - + spring-protobuf - + spring-quartz - + spring-reactive-kotlin spring-reactor spring-remoting @@ -700,9 +705,9 @@ spring-security-acl spring-security-angular/server spring-security-cache-control - + spring-security-client - + spring-security-core spring-security-mvc-boot spring-security-mvc-custom @@ -730,49 +735,50 @@ spring-state-machine spring-static-resources spring-swagger-codegen - + spring-thymeleaf - + spring-userservice - + spring-vault spring-vertx - + spring-webflux-amqp - + spring-zuul - + static-analysis stripe structurizr struts-2 - + testing-modules - + twilio Twitter4J - + undertow - + vavr vertx vertx-and-rxjava video-tutorials vraptor - + wicket - + xml xmlunit-2 xstream - + tensorflow-java spring-boot-flowable - + spring-security-kerberos + - + spring-context @@ -814,6 +820,7 @@ spring-boot-bootstrap spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-custom-starter greeter-spring-boot-autoconfigure greeter-spring-boot-sample-app @@ -910,8 +917,9 @@ persistence-modules/spring-data-eclipselink persistence-modules/spring-data-solr persistence-modules/spring-hibernate-5 - + spring-boot-flowable + spring-security-kerberos @@ -949,10 +957,11 @@ parent-spring-5 parent-java parent-kotlin - + core-java-concurrency-advanced core-kotlin core-kotlin-2 + core-kotlin-io jenkins/hello-world jws @@ -960,14 +969,15 @@ libraries persistence-modules/hibernate5 + persistence-modules/hibernate-mapping persistence-modules/java-jpa persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/jnosql - vaadin + vaadin - + integration-lite-first @@ -1038,8 +1048,9 @@ cdi checker-plugin core-groovy + core-groovy-2 - + core-java-8 core-java-8-2 @@ -1062,7 +1073,7 @@ core-scala couchbase custom-pmd - + dagger data-structures ddd @@ -1070,13 +1081,13 @@ disruptor dozer drools - dubbo - + dubbo + ethereum - + feign flyway-cdi-extension - + geotools google-cloud google-web-toolkit @@ -1090,17 +1101,19 @@ guava-modules guice - + hazelcast helidon httpclient + httpclient-simple hystrix - + image-processing immutables jackson jackson-2 + jackson-simple java-collections-conversions java-collections-maps java-collections-maps-2 @@ -1141,7 +1154,7 @@ kotlin-libraries - + libraries libraries-data @@ -1167,8 +1180,8 @@ mustache mybatis - - + + optaplanner orika osgi @@ -1178,9 +1191,9 @@ performance-tests protobuffer - + persistence-modules - + rabbitmq ratpack @@ -1192,8 +1205,8 @@ rule-engines rsocket rxjava - rxjava-2 - + rxjava-2 + @@ -1227,12 +1240,12 @@ parent-spring-5 parent-java parent-kotlin - + saas spark-java - + spring-4 - + spring-5 spring-5-data-reactive spring-5-mvc @@ -1242,7 +1255,7 @@ spring-5-reactive-security spring-5-security spring-5-security-oauth - + spring-activiti spring-akka spring-all @@ -1252,7 +1265,7 @@ spring-apache-camel spring-batch spring-bom - + spring-boot spring-boot-admin spring-boot-angular @@ -1262,6 +1275,7 @@ spring-boot-camel spring-boot-client + spring-boot-configuration spring-boot-crud spring-boot-ctx-fluent spring-boot-custom-starter @@ -1278,41 +1292,41 @@ spring-boot-property-exp spring-boot-security spring-boot-vue - + spring-cloud spring-cloud-bus spring-cloud-data-flow - + spring-core spring-cucumber - + spring-data-rest spring-data-rest-querydsl spring-dispatcher-servlet spring-drools - - spring-ehcache + + spring-ehcache spring-ejb spring-exceptions - + spring-freemarker - + spring-groovy - + spring-integration - + spring-jenkins-pipeline spring-jersey spring-jinq spring-jms spring-jooq - + spring-kafka spring-katharsis - + spring-ldap - + spring-mobile spring-mockito spring-mvc-forms-jsp @@ -1324,12 +1338,12 @@ spring-mvc-velocity spring-mvc-webflow spring-mvc-xml - + spring-protobuf - + spring-quartz - + spring-reactive-kotlin spring-reactor spring-remoting @@ -1342,13 +1356,13 @@ spring-rest-simple spring-resttemplate spring-roo - + spring-security-acl spring-security-angular/server spring-security-cache-control - + spring-security-client - + spring-security-core spring-security-mvc-boot spring-security-mvc-custom @@ -1375,42 +1389,42 @@ spring-state-machine spring-static-resources spring-swagger-codegen - + spring-thymeleaf - + spring-userservice - + spring-vault spring-vertx - + spring-webflux-amqp - + spring-zuul - + static-analysis stripe structurizr struts-2 - + testing-modules - + twilio Twitter4J - + undertow - + vavr vertx vertx-and-rxjava video-tutorials vraptor - + wicket - + xml xmlunit-2 xstream - + @@ -1444,8 +1458,8 @@ parent-spring-5 parent-java parent-kotlin - - core-java + + core-java core-java-concurrency-advanced core-kotlin core-kotlin-2 @@ -1458,9 +1472,9 @@ persistence-modules/hibernate5 persistence-modules/java-jpa persistence-modules/java-mongodb - persistence-modules/jnosql + persistence-modules/jnosql - vaadin + vaadin @@ -1486,15 +1500,15 @@ false false false - + 4.12 1.3 2.21.0 - + 1.7.21 1.1.7 - + 2.21.0 3.7.0 diff --git a/spring-boot-configuration/.gitignore b/spring-boot-configuration/.gitignore new file mode 100644 index 0000000000..153c9335eb --- /dev/null +++ b/spring-boot-configuration/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/spring-boot-configuration/README.MD b/spring-boot-configuration/README.MD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-configuration/pom.xml b/spring-boot-configuration/pom.xml new file mode 100644 index 0000000000..2ecef7bb02 --- /dev/null +++ b/spring-boot-configuration/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + com.baeldung + spring-boot-configuration + 0.0.1-SNAPSHOT + spring-boot-configuration + Demo project for Spring Boot configuration + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java b/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java new file mode 100644 index 0000000000..b4f5681475 --- /dev/null +++ b/spring-boot-configuration/src/main/java/com/baeldung/springbootconfiguration/SpringBootConfigurationApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springbootconfiguration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootConfigurationApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootConfigurationApplication.class, args); + } + +} diff --git a/spring-boot-configuration/src/main/resources/application-tomcat.properties b/spring-boot-configuration/src/main/resources/application-tomcat.properties new file mode 100644 index 0000000000..d7c1ba9ac3 --- /dev/null +++ b/spring-boot-configuration/src/main/resources/application-tomcat.properties @@ -0,0 +1,23 @@ +# server configuration +server.port=80 +server.address=127.0.0.1 + +## Error handling configuration +server.error.whitelabel.enabled=true +server.error.path=/user-error +server.error.include-exception=true +server.error.include-stacktrace=always + +## Server connections configuration +server.tomcat.max-threads=200 +server.connection-timeout=5s +server.max-http-header-size=8KB +server.tomcat.max-swallow-size=2MB +server.tomcat.max-http-post-size=2MB + +## Access logs configuration +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.directory=logs +server.tomcat.accesslog.file-date-format=yyyy-MM-dd +server.tomcat.accesslog.prefix=access_log +server.tomcat.accesslog.suffix=.log diff --git a/spring-boot-configuration/src/main/resources/application.properties b/spring-boot-configuration/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-boot-configuration/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java b/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..d6b2b50a2f --- /dev/null +++ b/spring-boot-configuration/src/test/java/com/baeldung/springbootconfiguration/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.springbootconfiguration; + +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 +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-boot-mvc-birt/pom.xml b/spring-boot-mvc-birt/pom.xml index 05d3f3865a..8f41e8410a 100644 --- a/spring-boot-mvc-birt/pom.xml +++ b/spring-boot-mvc-birt/pom.xml @@ -75,7 +75,7 @@ 2.1.1.RELEASE - com.baeldung.springbootmvc.SpringBootMvcApplication + com.baeldung.birt.engine.ReportEngineApplication 1.8 1.8 diff --git a/spring-boot-rest/README.md b/spring-boot-rest/README.md index dc0a573c78..b28192cf62 100644 --- a/spring-boot-rest/README.md +++ b/spring-boot-rest/README.md @@ -7,7 +7,7 @@ Module for the articles that are part of the Spring REST E-book: 5. [Entity To DTO Conversion for a Spring REST API](https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application) 6. [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) 7. [REST API Discoverability and HATEOAS](http://www.baeldung.com/restful-web-service-discoverability) -8. +8. [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial) 9. [REST Pagination in Spring](http://www.baeldung.com/rest-api-pagination-in-spring) 10. [Test a REST API with Java](http://www.baeldung.com/integration-testing-a-rest-api) @@ -16,4 +16,3 @@ Module for the articles that are part of the Spring REST E-book: - [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring) - [Testing REST with multiple MIME types](http://www.baeldung.com/testing-rest-api-with-multiple-media-types) - [Testing Web APIs with Postman Collections](https://www.baeldung.com/postman-testing-collections) -- [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial) \ No newline at end of file diff --git a/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java new file mode 100644 index 0000000000..97f001a9e5 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/component/OtherComponent.java @@ -0,0 +1,19 @@ +package com.baeldung.component; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class OtherComponent { + + private static final Logger LOG = LoggerFactory.getLogger(OtherComponent.class); + + public void processData() { + LOG.trace("This is a TRACE log from another package"); + LOG.debug("This is a DEBUG log from another package"); + LOG.info("This is an INFO log from another package"); + LOG.error("This is an ERROR log from another package"); + } + +} diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java new file mode 100644 index 0000000000..ed8218c6a3 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.testloglevel; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.baeldung.boot.Application; + +@SpringBootApplication(scanBasePackages = {"com.baeldung.testloglevel", "com.baeldung.component"}) +public class TestLogLevelApplication { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java new file mode 100644 index 0000000000..22078562b4 --- /dev/null +++ b/spring-boot-testing/src/main/java/com/baeldung/testloglevel/TestLogLevelController.java @@ -0,0 +1,31 @@ +package com.baeldung.testloglevel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.component.OtherComponent; + +@RestController +public class TestLogLevelController { + + private static final Logger LOG = LoggerFactory.getLogger(TestLogLevelController.class); + + @Autowired + private OtherComponent otherComponent; + + @GetMapping("/testLogLevel") + public String testLogLevel() { + LOG.trace("This is a TRACE log"); + LOG.debug("This is a DEBUG log"); + LOG.info("This is an INFO log"); + LOG.error("This is an ERROR log"); + + otherComponent.processData(); + + return "Added some log output to console..."; + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java new file mode 100644 index 0000000000..7a1eb4adbe --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackMultiProfileTestLogLevelIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logback-test2") +public class LogbackMultiProfileTestLogLevelIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintTraceLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("TRACE"); + } + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenNoTraceLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("TRACE"); + } + + @Test + public void givenErrorRootLevelAndTraceLevelForOurPackage_whenCall_thenPrintErrorLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("ERROR"); + assertThatOutputContainsLogForOtherPackages("ERROR"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java new file mode 100644 index 0000000000..af3bafdc2e --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/LogbackTestLogLevelIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logback-test") +public class LogbackTestLogLevelIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("DEBUG"); + } + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("DEBUG"); + } + + @Test + public void givenErrorRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintErrorLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("ERROR"); + assertThatOutputContainsLogForOtherPackages("ERROR"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java new file mode 100644 index 0000000000..5609ce6c01 --- /dev/null +++ b/spring-boot-testing/src/test/java/com/baeldung/testloglevel/TestLogLevelWithProfileIntegrationTest.java @@ -0,0 +1,70 @@ +package com.baeldung.testloglevel; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.rule.OutputCapture; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = TestLogLevelApplication.class) +@EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class) +@ActiveProfiles("logging-test") +public class TestLogLevelWithProfileIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String baseUrl = "/testLogLevel"; + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintDebugLogsForOurPackage() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("DEBUG"); + } + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenNoDebugLogsForOtherPackages() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputDoesntContainLogForOtherPackages("DEBUG"); + } + + @Test + public void givenInfoRootLevelAndDebugLevelForOurPackage_whenCall_thenPrintInfoLogs() { + ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class); + + assertThat(response.getStatusCode().value()).isEqualTo(200); + assertThatOutputContainsLogForOurPackage("INFO"); + assertThatOutputContainsLogForOtherPackages("INFO"); + } + + private void assertThatOutputContainsLogForOurPackage(String level) { + assertThat(outputCapture.toString()).containsPattern("TestLogLevelController.*" + level + ".*"); + } + + private void assertThatOutputDoesntContainLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).doesNotContain(level); + } + + private void assertThatOutputContainsLogForOtherPackages(String level) { + assertThat(outputCapture.toString().replaceAll("(?m)^.*TestLogLevelController.*$", "")).contains(level); + } + +} diff --git a/spring-boot-testing/src/test/resources/application-logback-test.properties b/spring-boot-testing/src/test/resources/application-logback-test.properties new file mode 100644 index 0000000000..587302fa01 --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logback-test.properties @@ -0,0 +1 @@ +logging.config=classpath:logback-test.xml diff --git a/spring-boot-testing/src/test/resources/application-logback-test2.properties b/spring-boot-testing/src/test/resources/application-logback-test2.properties new file mode 100644 index 0000000000..aeed46e3ca --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logback-test2.properties @@ -0,0 +1 @@ +logging.config=classpath:logback-multiprofile.xml \ No newline at end of file diff --git a/spring-boot-testing/src/test/resources/application-logging-test.properties b/spring-boot-testing/src/test/resources/application-logging-test.properties new file mode 100644 index 0000000000..b5adb4cc11 --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-logging-test.properties @@ -0,0 +1,2 @@ +logging.level.com.baeldung.testloglevel=DEBUG +logging.level.root=INFO \ No newline at end of file diff --git a/spring-boot-testing/src/test/resources/logback-multiprofile.xml b/spring-boot-testing/src/test/resources/logback-multiprofile.xml new file mode 100644 index 0000000000..be790234f2 --- /dev/null +++ b/spring-boot-testing/src/test/resources/logback-multiprofile.xml @@ -0,0 +1,18 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + diff --git a/spring-boot-testing/src/test/resources/logback-test.xml b/spring-boot-testing/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..0528aa88f3 --- /dev/null +++ b/spring-boot-testing/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/spring-core/pom.xml b/spring-core/pom.xml index d348d742e7..814addecdd 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -10,9 +10,9 @@ com.baeldung - parent-spring-4 + parent-spring-5 0.0.1-SNAPSHOT - ../parent-spring-4 + ../parent-spring-5 diff --git a/spring-security-kerberos/README.md b/spring-security-kerberos/README.md new file mode 100644 index 0000000000..0338c2058c --- /dev/null +++ b/spring-security-kerberos/README.md @@ -0,0 +1,10 @@ +## @PreFilter and @PostFilter annotations + +### Build the Project ### + +``` +mvn clean install +``` + +### Relevant Articles: +- [Spring Security – Kerberos](http://www.baeldung.com/xxxxxx) diff --git a/spring-security-kerberos/pom.xml b/spring-security-kerberos/pom.xml new file mode 100644 index 0000000000..35c4ba4926 --- /dev/null +++ b/spring-security-kerberos/pom.xml @@ -0,0 +1,61 @@ + + 4.0.0 + com.baeldung + spring-security-kerberos + 0.1-SNAPSHOT + spring-security-kerberos + war + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security.kerberos + spring-security-kerberos-core + 1.0.1.RELEASE + + + org.springframework.security.kerberos + spring-security-kerberos-web + 1.0.1.RELEASE + + + org.springframework.security.kerberos + spring-security-kerberos-client + 1.0.1.RELEASE + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + org.apache.maven.plugins + maven-war-plugin + + + + diff --git a/spring-security-kerberos/src/main/java/org/baeldung/Application.java b/spring-security-kerberos/src/main/java/org/baeldung/Application.java new file mode 100644 index 0000000000..39c2b51356 --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/Application.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java new file mode 100644 index 0000000000..49a1cf0a8e --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/config/WebSecurityConfig.java @@ -0,0 +1,87 @@ +package org.baeldung.config; + +import org.baeldung.security.DummyUserDetailsService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider; +import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider; +import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient; +import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator; +import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter; +import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest() + .authenticated() + .and() + .addFilterBefore(spnegoAuthenticationProcessingFilter(authenticationManagerBean()), BasicAuthenticationFilter.class); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(kerberosAuthenticationProvider()) + .authenticationProvider(kerberosServiceAuthenticationProvider()); + } + + @Bean + public KerberosAuthenticationProvider kerberosAuthenticationProvider() { + KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider(); + SunJaasKerberosClient client = new SunJaasKerberosClient(); + client.setDebug(true); + provider.setKerberosClient(client); + provider.setUserDetailsService(dummyUserDetailsService()); + return provider; + } + + @Bean + public SpnegoEntryPoint spnegoEntryPoint() { + return new SpnegoEntryPoint("/login"); + } + + @Bean + public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(AuthenticationManager authenticationManager) { + SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter(); + filter.setAuthenticationManager(authenticationManager); + return filter; + } + + @Bean + public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() { + KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider(); + provider.setTicketValidator(sunJaasKerberosTicketValidator()); + provider.setUserDetailsService(dummyUserDetailsService()); + return provider; + } + + @Bean + public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() { + SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator(); + ticketValidator.setServicePrincipal("HTTP/demo.kerberos.bealdung.com@baeldung.com"); + ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab")); + ticketValidator.setDebug(true); + return ticketValidator; + } + + @Bean + public DummyUserDetailsService dummyUserDetailsService() { + return new DummyUserDetailsService(); + } + +} \ No newline at end of file diff --git a/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java new file mode 100644 index 0000000000..10d71fca8f --- /dev/null +++ b/spring-security-kerberos/src/main/java/org/baeldung/security/DummyUserDetailsService.java @@ -0,0 +1,16 @@ +package org.baeldung.security; + +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +public class DummyUserDetailsService implements UserDetailsService { + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return new User(username, "notUsed", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_USER")); + } + +} \ No newline at end of file diff --git a/spring-security-rest-basic-auth/README.md b/spring-security-rest-basic-auth/README.md index 30da3afbcf..0a48a747c2 100644 --- a/spring-security-rest-basic-auth/README.md +++ b/spring-security-rest-basic-auth/README.md @@ -8,6 +8,5 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Basic Authentication with the RestTemplate](http://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) - [HttpClient Timeout](http://www.baeldung.com/httpclient-timeout) -- [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl) - [A Custom Filter in the Spring Security Filter Chain](http://www.baeldung.com/spring-security-custom-filter) - [Spring Security Basic Authentication](http://www.baeldung.com/spring-security-basic-authentication) diff --git a/spring-security-rest-basic-auth/pom.xml b/spring-security-rest-basic-auth/pom.xml index ca5c4c38e6..3c7f8eaa2b 100644 --- a/spring-security-rest-basic-auth/pom.xml +++ b/spring-security-rest-basic-auth/pom.xml @@ -272,8 +272,8 @@ - 4.4.5 - 4.5.3 + 4.4.11 + 4.5.8 1.2 diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index cd342ccd11..c528a34e21 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -162,6 +162,11 @@ commons-collections ${commons-collections.version} + + + org.springframework.boot + spring-boot-starter-security + @@ -179,6 +184,12 @@ json-schema-validator test + + com.github.scribejava + scribejava-apis + ${scribejava.version} + test + @@ -211,6 +222,8 @@ 3.0.1 3.0.1 + + 2.5.3 diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java new file mode 100644 index 0000000000..aff765dfa3 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicAuthenticationLiveTest.java @@ -0,0 +1,38 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-security-rest-basic-auth module. + * @see spring-security-rest-basic-auth module + * + */ +public class BasicAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenBasicAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + given().auth() + .basic(USER, PASSWORD) + .when() + .get(SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java new file mode 100644 index 0000000000..02138f22e3 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/BasicPreemtiveAuthenticationLiveTest.java @@ -0,0 +1,56 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-boot-admin/spring-boot-admin-server module. + * @see spring-boot-admin/spring-boot-admin-server module + * + */ +public class BasicPreemtiveAuthenticationLiveTest { + + private static final String USER = "admin"; + private static final String PASSWORD = "admin"; + private static final String SVC_URL = "http://localhost:8080/api/applications/"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-security-mvc-digest-auth module + * + */ +public class DigestAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-mvc-digest-auth/homepage.html"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenFormAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + given().auth() + .digest(USER, PASSWORD) + .when() + .get(SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("This is the body of the sample view")); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java new file mode 100644 index 0000000000..66ae9fb162 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/FormAuthenticationLiveTest.java @@ -0,0 +1,57 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.isEmptyString; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.authentication.FormAuthConfig; + +/** + * For this Live Test we need: + * * a running instance of the service located in the spring-security-mvc-login module. + * @see spring-security-mvc-login module + * + */ +public class FormAuthenticationLiveTest { + + private static final String USER = "user1"; + private static final String PASSWORD = "user1Pass"; + private static final String SVC_URL = "http://localhost:8080/spring-security-mvc-login/secured"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenLoginFormResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-boot-admin/spring-boot-admin-server module + * + */ +public class FormAutoconfAuthenticationLiveTest { + + private static final String USER = "admin"; + private static final String PASSWORD = "admin"; + private static final String SVC_URL = "http://localhost:8080/ger1/api/applications/"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .content(containsString("spring-security-oauth/oauth-authorization-server module + * + * * a running instance of the service located in the spring-security-oauth repo - oauth-resource-server-1 module. + * @see spring-security-oauth/oauth-resource-server-1 module + * + */ +public class OAuth2AuthenticationLiveTest { + + private static final String USER = "john"; + private static final String PASSWORD = "123"; + private static final String CLIENT_ID = "fooClientIdPassword"; + private static final String SECRET = "secret"; + private static final String AUTH_SVC_TOKEN_URL = "http://localhost:8081/spring-security-oauth-server/oauth/token"; + private static final String RESOURCE_SVC_URL = "http://localhost:8082/spring-security-oauth-resource/foos/1"; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(RESOURCE_SVC_URL).then() + .assertThat() + .statusCode(HttpStatus.UNAUTHORIZED.value()); + } + + @Test + public void givenAccessTokenAuthentication_whenRequestSecuredResource_thenResourceRetrieved() { + String accessToken = given().auth() + .basic(CLIENT_ID, SECRET) + .formParam("grant_type", "password") + .formParam("username", USER) + .formParam("password", PASSWORD) + .formParam("scope", "read foo") + .when() + .post(AUTH_SVC_TOKEN_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .extract() + .path("access_token"); + + given().auth() + .oauth2(accessToken) + .when() + .get(RESOURCE_SVC_URL) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .body("$", hasKey("id")) + .body("$", hasKey("name")); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java new file mode 100644 index 0000000000..c720bc04e4 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/authentication/OAuthAuthenticationLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.restassured.authentication; + +import static io.restassured.RestAssured.get; +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.hasKey; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import io.restassured.http.ContentType; + +/** + * For this Live Test we need to obtain a valid Access Token and Token Secret: + * * start spring-mvc-simple application in debug mode + * @see spring-mvc-simple module + * * calling localhost:8080/spring-mvc-simple/twitter/authorization/ using the browser + * * debug the callback function where we can obtain the fields + */ +public class OAuthAuthenticationLiveTest { + + // We can obtain these two from the spring-mvc-simple / TwitterController class + private static final String OAUTH_API_KEY = "PSRszoHhRDVhyo2RIkThEbWko"; + private static final String OAUTH_API_SECRET = "prpJbz03DcGRN46sb4ucdSYtVxG8unUKhcnu3an5ItXbEOuenL"; + private static final String TWITTER_ENDPOINT = "https://api.twitter.com/1.1/account/settings.json"; + /* We can obtain the following by: + * - starting the spring-mvc-simple application + * - calling localhost:8080/spring-mvc-simple/twitter/authorization/ + * - debugging the callback function */ + private static final String ACCESS_TOKEN = "..."; + private static final String TOKEN_SECRET = "..."; + + @Test + public void givenNoAuthentication_whenRequestSecuredResource_thenUnauthorizedResponse() { + get(TWITTER_ENDPOINT).then() + .assertThat() + .statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @Test + public void givenAccessTokenAuthentication_whenRequestSecuredResource_thenResourceIsRequested() { + given().accept(ContentType.JSON) + .auth() + .oauth(OAUTH_API_KEY, OAUTH_API_SECRET, ACCESS_TOKEN, TOKEN_SECRET) + .when() + .get(TWITTER_ENDPOINT) + .then() + .assertThat() + .statusCode(HttpStatus.OK.value()) + .body("$", hasKey("geo_enabled")) + .body("$", hasKey("language")); + } + +} diff --git a/vaadin/pom.xml b/vaadin/pom.xml index d24b3dff1b..145a6af293 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -33,22 +33,6 @@ javax.servlet-api provided - - com.vaadin - vaadin-server - - - com.vaadin - vaadin-push - - - com.vaadin - vaadin-client-compiled - - - com.vaadin - vaadin-themes - org.springframework.boot @@ -183,9 +167,9 @@ 3.0.1 - 7.7.10 - 8.0.6 - 10.0.1 + 10.0.11 + 10.0.11 + 10.0.11 9.3.9.v20160517 UTF-8 1.8 diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java deleted file mode 100644 index 1b3733ad74..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.baeldung.introduction; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.servlet.annotation.WebServlet; - -import com.vaadin.annotations.Push; -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.VaadinServletConfiguration; -import com.vaadin.data.Validator.InvalidValueException; -import com.vaadin.data.fieldgroup.BeanFieldGroup; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.server.ExternalResource; -import com.vaadin.server.FontAwesome; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinServlet; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Grid; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeButton; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PasswordField; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; -import com.vaadin.ui.TwinColSelect; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; - -@SuppressWarnings("serial") -@Push -@Theme("mytheme") -public class VaadinUI extends UI { - - private Label currentTime; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void init(VaadinRequest vaadinRequest) { - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSpacing(true); - verticalLayout.setMargin(true); - final GridLayout gridLayout = new GridLayout(3, 2); - gridLayout.setSpacing(true); - gridLayout.setMargin(true); - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSpacing(true); - horizontalLayout.setMargin(true); - final FormLayout formLayout = new FormLayout(); - formLayout.setSpacing(true); - formLayout.setMargin(true); - final GridLayout buttonLayout = new GridLayout(3, 5); - buttonLayout.setMargin(true); - buttonLayout.setSpacing(true); - - final Label label = new Label(); - label.setId("Label"); - label.setValue("Label Value"); - label.setCaption("Label"); - gridLayout.addComponent(label); - - final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/")); - link.setId("Link"); - link.setTargetName("_blank"); - gridLayout.addComponent(link); - - final TextField textField = new TextField(); - textField.setId("TextField"); - textField.setCaption("TextField:"); - textField.setValue("TextField Value"); - textField.setIcon(FontAwesome.USER); - gridLayout.addComponent(textField); - - final TextArea textArea = new TextArea(); - textArea.setCaption("TextArea"); - textArea.setId("TextArea"); - textArea.setValue("TextArea Value"); - gridLayout.addComponent(textArea); - - final DateField dateField = new DateField("DateField", new Date(0)); - dateField.setId("DateField"); - gridLayout.addComponent(dateField); - - final PasswordField passwordField = new PasswordField(); - passwordField.setId("PasswordField"); - passwordField.setCaption("PasswordField:"); - passwordField.setValue("password"); - gridLayout.addComponent(passwordField); - - final RichTextArea richTextArea = new RichTextArea(); - richTextArea.setCaption("Rich Text Area"); - richTextArea.setValue("

RichTextArea

"); - richTextArea.setSizeFull(); - - Panel richTextPanel = new Panel(); - richTextPanel.setContent(richTextArea); - - final InlineDateField inlineDateField = new InlineDateField(); - inlineDateField.setValue(new Date(0)); - inlineDateField.setCaption("Inline Date Field"); - horizontalLayout.addComponent(inlineDateField); - - Button normalButton = new Button("Normal Button"); - normalButton.setId("NormalButton"); - normalButton.addClickListener(e -> { - label.setValue("CLICK"); - }); - buttonLayout.addComponent(normalButton); - - Button tinyButton = new Button("Tiny Button"); - tinyButton.addStyleName("tiny"); - buttonLayout.addComponent(tinyButton); - - Button smallButton = new Button("Small Button"); - smallButton.addStyleName("small"); - buttonLayout.addComponent(smallButton); - - Button largeButton = new Button("Large Button"); - largeButton.addStyleName("large"); - buttonLayout.addComponent(largeButton); - - Button hugeButton = new Button("Huge Button"); - hugeButton.addStyleName("huge"); - buttonLayout.addComponent(hugeButton); - - Button disabledButton = new Button("Disabled Button"); - disabledButton.setDescription("This button cannot be clicked"); - disabledButton.setEnabled(false); - buttonLayout.addComponent(disabledButton); - - Button dangerButton = new Button("Danger Button"); - dangerButton.addStyleName("danger"); - buttonLayout.addComponent(dangerButton); - - Button friendlyButton = new Button("Friendly Button"); - friendlyButton.addStyleName("friendly"); - buttonLayout.addComponent(friendlyButton); - - Button primaryButton = new Button("Primary Button"); - primaryButton.addStyleName("primary"); - buttonLayout.addComponent(primaryButton); - - NativeButton nativeButton = new NativeButton("Native Button"); - buttonLayout.addComponent(nativeButton); - - Button iconButton = new Button("Icon Button"); - iconButton.setIcon(FontAwesome.ALIGN_LEFT); - buttonLayout.addComponent(iconButton); - - Button borderlessButton = new Button("BorderLess Button"); - borderlessButton.addStyleName("borderless"); - buttonLayout.addComponent(borderlessButton); - - Button linkButton = new Button("Link Button"); - linkButton.addStyleName("link"); - buttonLayout.addComponent(linkButton); - - Button quietButton = new Button("Quiet Button"); - quietButton.addStyleName("quiet"); - buttonLayout.addComponent(quietButton); - - horizontalLayout.addComponent(buttonLayout); - - final CheckBox checkbox = new CheckBox("CheckBox"); - checkbox.setValue(true); - checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue())); - formLayout.addComponent(checkbox); - - List numbers = new ArrayList(); - numbers.add("One"); - numbers.add("Ten"); - numbers.add("Eleven"); - ComboBox comboBox = new ComboBox("ComboBox"); - comboBox.addItems(numbers); - formLayout.addComponent(comboBox); - - ListSelect listSelect = new ListSelect("ListSelect"); - listSelect.addItems(numbers); - listSelect.setRows(2); - formLayout.addComponent(listSelect); - - NativeSelect nativeSelect = new NativeSelect("NativeSelect"); - nativeSelect.addItems(numbers); - formLayout.addComponent(nativeSelect); - - TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); - twinColSelect.addItems(numbers); - - Grid grid = new Grid("Grid"); - grid.setColumns("Column1", "Column2", "Column3"); - grid.addRow("Item1", "Item2", "Item3"); - grid.addRow("Item4", "Item5", "Item6"); - - Panel panel = new Panel("Panel"); - panel.setContent(grid); - panel.setSizeUndefined(); - - Panel serverPushPanel = new Panel("Server Push"); - FormLayout timeLayout = new FormLayout(); - timeLayout.setSpacing(true); - timeLayout.setMargin(true); - currentTime = new Label("No TIME..."); - timeLayout.addComponent(currentTime); - serverPushPanel.setContent(timeLayout); - serverPushPanel.setSizeUndefined(); - ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1); - Runnable task = () -> { - currentTime.setValue("Current Time : " + Instant.now()); - }; - scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); - - FormLayout dataBindingLayout = new FormLayout(); - dataBindingLayout.setSpacing(true); - dataBindingLayout.setMargin(true); - - BindData bindData = new BindData("BindData"); - BeanFieldGroup beanFieldGroup = new BeanFieldGroup(BindData.class); - beanFieldGroup.setItemDataSource(bindData); - TextField bindedTextField = (TextField) beanFieldGroup.buildAndBind("BindName", "bindName"); - bindedTextField.setWidth("250px"); - dataBindingLayout.addComponent(bindedTextField); - - FormLayout validatorLayout = new FormLayout(); - validatorLayout.setSpacing(true); - validatorLayout.setMargin(true); - - HorizontalLayout textValidatorLayout = new HorizontalLayout(); - textValidatorLayout.setSpacing(true); - textValidatorLayout.setMargin(true); - - TextField stringValidator = new TextField(); - stringValidator.setNullSettingAllowed(true); - stringValidator.setNullRepresentation(""); - stringValidator.addValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5, true)); - stringValidator.setValidationVisible(false); - textValidatorLayout.addComponent(stringValidator); - Button buttonStringValidator = new Button("Validate String"); - buttonStringValidator.addClickListener(e -> { - try { - stringValidator.setValidationVisible(false); - stringValidator.validate(); - } catch (InvalidValueException err) { - stringValidator.setValidationVisible(true); - } - }); - textValidatorLayout.addComponent(buttonStringValidator); - - validatorLayout.addComponent(textValidatorLayout); - verticalLayout.addComponent(gridLayout); - verticalLayout.addComponent(richTextPanel); - verticalLayout.addComponent(horizontalLayout); - verticalLayout.addComponent(formLayout); - verticalLayout.addComponent(twinColSelect); - verticalLayout.addComponent(panel); - verticalLayout.addComponent(serverPushPanel); - verticalLayout.addComponent(dataBindingLayout); - verticalLayout.addComponent(validatorLayout); - setContent(verticalLayout); - } - - @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } -}